Esempio n. 1
0
    def shunting_yard(self, elements: Queue):
        """Does the shunting yard algorithm to produce something that is ready for rpn"""
        operator_stack = Stack()
        while not elements.is_empty():
            element = elements.pop()

            if isinstance(element, numbers.Number):
                self.output_queue.push(element)
            elif isinstance(element, Function) or element == "(":
                operator_stack.push(element)
            elif element == ")":
                while operator_stack.peek() != "(":
                    self.output_queue.push(operator_stack.pop())

                # Pop (
                if operator_stack.peek() == "(":
                    operator_stack.pop()

                if not operator_stack.is_empty() and isinstance(operator_stack.peek(), Function):
                    self.output_queue.push(operator_stack.pop())
            elif isinstance(element, Operator):
                intermediate_storage = Stack()
                while ((not operator_stack.is_empty())
                       and (not operator_stack.peek() == "(")
                       and operator_stack.peek().strength < element.strength):
                    intermediate_storage.push(operator_stack.pop())

                while not intermediate_storage.is_empty():
                    operator_stack.push(intermediate_storage.pop())

                operator_stack.push(element)

        while not operator_stack.is_empty():
            self.output_queue.push(operator_stack.pop())
Esempio n. 2
0
    def __init__(self):
        """Initialize a Dispatcher.

        @type self: Dispatcher
        @type _waitlist: Queue of Rider
        @type _fleet: PriorityQueue of Driver
        @rtype: None
        """
        self._waitlist = Queue()
        self._fleet = []
Esempio n. 3
0
    def __init__(self):
        """Initialize a Dispatcher.

        @type self: Dispatcher
        @type waiting_riders
        @type availalbe_drivers
        @rtype: None
        """

        self._available_drivers = []
        self._waiting_riders = Queue()
Esempio n. 4
0
 def test_queue(self):
     test_queue = Queue()
     for i in range(0, 5):
         test_queue.push(i)
     counter = 0
     while test_queue.is_empty() is not True:
         self.assertTrue(test_queue.peek() == counter)
         test_queue.pop()
         counter += 1
     self.assertTrue(test_queue.is_empty())
Esempio n. 5
0
def is_reachable(road_network, s_vid, e_vid):
    """
    Return True if there exist a path from s_vid to e_vid, otherwise return False.

    The algorithm is basic Breadth-First-Search (with early exit).

    :param road_network: RoadNetwork
    :param s_vid: int
    :param e_vid: int
    :return: bool
    """
    frontier = Queue()
    frontier.put(s_vid)
    came_from = dict()
    came_from[s_vid] = None

    while not frontier.empty():
        current = frontier.get()
        if current == e_vid:
            return True
        for neighbor in road_network.get_neighbors(current):
            if neighbor not in came_from:
                frontier.put(neighbor)
                came_from[neighbor] = current
    return False
Esempio n. 6
0
def bfs(road_network, s_vid, e_vid):
    """
    Return the path from vertex s_vid to vertex e_vid using Dijkstra's algorithm.

    The implementation is the same as the function is_reachable(), except that instead of bool type, we return a Path
    found by Breadth First Search.

    :param road_network: RoadNetwork
    :param s_vid: int
    :param e_vid: int
    :return: Path
    """
    frontier = Queue()
    frontier.put(s_vid)
    came_from = dict()
    came_from[s_vid] = None

    while not frontier.empty():
        current = frontier.get()
        if current == e_vid:
            break
        for neighbor in road_network.get_neighbors(current):
            if neighbor not in came_from:
                frontier.put(neighbor)
                came_from[neighbor] = current
    return construct_path(road_network, s_vid, e_vid, came_from)
Esempio n. 7
0
 def test_shunting_yard(self):
     """Test that shunting yard works correctly"""
     calc = Calc()
     elements = Queue([
         Function(np.exp), '(', 1,
         Operator(np.add, 0), 2,
         Operator(np.multiply, 1), 3, ")"
     ])
     calc.shunting_yard(elements)
     expected_output = Queue([
         1, 2, 3,
         Operator(np.multiply, 1),
         Operator(np.add, 0),
         Function(np.exp)
     ])
     self.assertEqual(str(expected_output), str(calc.output_queue))
Esempio n. 8
0
    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),
            'SQUARE': Function(numpy.square)
        }

        self.operators = {
            'PLUSS': Operator(numpy.add, 0),
            'GANGE': Operator(numpy.multiply, 1),
            'DELE': Operator(numpy.divide, 1),
            'MINUS': Operator(numpy.subtract, 0)
        }
        self.output_queue = Queue()
Esempio n. 9
0
 def test_parse_text(self):
     """Test that text parser works correctly"""
     calc = Calc()
     output = calc.parse_text("2 multiply 3 add 1")
     expected_output = Queue(
         [2.0, Operator(np.multiply, 1), 3.0,
          Operator(np.add, 0), 1.0])
     self.assertEqual(str(expected_output), str(output))
Esempio n. 10
0
    def __init__(self):
        self.functions = {
            'EXP': Function(np.exp),
            'LOG': Function(np.log),
            'SIN': Function(np.sin),
            'COS': Function(np.cos),
            'SQRT': Function(np.sqrt)
        }
        self.operators = {
            'PLUS': Operator(np.add, 0),
            'ADD': Operator(np.add, 0),
            'TIMES': Operator(np.multiply, 1),
            'MULTIPLY': Operator(np.multiply, 1),
            'DIVIDE': Operator(np.divide, 1),
            'MINUS': Operator(np.subtract, 0),
            'SUBTRACT': Operator(np.subtract, 0)
        }

        self.output_queue = Queue()
Esempio n. 11
0
 def test_rpn(self):
     """Test that rpn works correctly"""
     calc = Calc()
     calc.output_queue = Queue([
         1, 2, 3,
         Operator(np.multiply, 1),
         Operator(np.add, 0),
         Function(np.exp)
     ])
     self.assertEqual(round(calc.rpn(), 2), 1096.63)
Esempio n. 12
0
    def __init__(self,
                 failed_queries=None,
                 waiting_queries=None,
                 completed_queries=None,
                 cancelled_queries=None):
        """
        Initialize a Dispatcher.

        :param failed_queries: a Queue stores the queries that the dispatcher failed to find a taxi, these queries
        need to be processed in the next timestamp
        :param waiting_queries: a dict stores the queries that are dispatched a taxi and under waiting
        :param completed_queries: a list stores successfully completed queries
        :param cancelled_queries: a list stores cancelled queries
        :type failed_queries: Queue[Query]
        :type waiting_queries: dict[int, Query]
        :type completed_queries: list[Query]
        :type cancelled_queries: list[Query]
        :return: None
        """

        if failed_queries is None:
            self.failed_queries = Queue()
        else:
            self.failed_queries = failed_queries

        if waiting_queries is None:
            self.waiting_queries = dict()
        else:
            self.waiting_queries = waiting_queries

        if completed_queries is None:
            self.completed_queries = list()
        else:
            self.completed_queries = completed_queries

        if cancelled_queries is None:
            self.cancelled_queries = list()
        else:
            self.cancelled_queries = cancelled_queries
Esempio n. 13
0
    def parse_text(self, text):
        """Parses human readable text into something that is ready to be sorted by shunting_yard"""
        text = text.replace(" ", "").upper()
        index = 0
        shunting_yard_ready = Queue()

        while index < len(text):
            text = text[index:]

            # Check for number
            match = re.search("^[-0123456789.]+", text)
            if match is not None:
                shunting_yard_ready.push(float(match.group(0)))
                index = match.end(0)
                continue

            # Check for function
            match = re.search("|".join(["^" + func for func in self.functions.keys()]), text)
            if match is not None:
                shunting_yard_ready.push(self.functions[match.group(0)])
                index = match.end(0)
                continue

            # Check for operator
            match = re.search("|".join(["^" + op for op in self.operators.keys()]), text)
            if match is not None:
                shunting_yard_ready.push(self.operators[match.group(0)])
                index = match.end(0)
                continue

            # Check for paranthases
            match = re.search("^[()]", text)
            if match is not None:
                shunting_yard_ready.push(match.group(0))
                index = match.end(0)
                continue

        return shunting_yard_ready
Esempio n. 14
0
 def __init__(self):
     # Define the functions supported by linking them to Python
     # functions. These can be made elsewhere in the program,
     # or imported (e.g., from numpy)
     self.functions = {
         'EXP': Function(numpy.exp),
         'LOG': Function(numpy.log),
         'SIN': Function(numpy.sin),
         'COS': Function(numpy.cos),
         'SQRT': Function(numpy.sqrt)
     }
     # Define the operators supported
     # Link them to Python functions (here: from numpy)
     self.operators = {
         'PLUSS': Operator(numpy.add, 0),
         'GANGE': Operator(numpy.multiply, 1),
         'DELE': Operator(numpy.divide, 1),
         'MINUS': Operator(numpy.subtract, 0)
     }
     # Define the output−queue . The parse text method fills this with RPN.
     # The evaluate_output_queue method evaluates it
     self.output_queue = Queue()
     self.input_queue = Queue()
Esempio n. 15
0
    def test_queue(self):
        """Test Queue class"""

        queue = Queue()
        for num in self.test_list:
            queue.push(num)

        index = 0
        while not queue.is_empty():
            num = queue.pop()
            self.assertEqual(num, self.test_list[index])
            index += 1
Esempio n. 16
0
class Dispatcher:
    def __init__(self,
                 failed_queries=None,
                 waiting_queries=None,
                 completed_queries=None,
                 cancalled_queries=None):
        '''
        Initialize a Dispatcher.

        :param failed_queries: a Queue stores the queries that the dispatcher failed to find a taxi, these queries
        need to be processed in the next timestamp
        :param waiting_queries: a dict stores the queries that are dispatched a taxi and under waiting
        :param completed_queries: a list stores successfully completed queries
        :param cancelled_queries: a list stores cancelled queries
        :type failed_queries: Queue[Query]
        :type waiting_queries: dict[int, Query]
        :type completed_queries: list[Query]
        :type cancelled_queries: list[Query]
        :return: None
        '''

        if failed_queries is None:
            self.failed_queries = Queue()
        else:
            self.failed_queries = failed_queries

        if waiting_queries is None:
            self.waiting_queries = dict()
        else:
            self.waiting_queries = waiting_queries

        if completed_queries is None:
            self.completed_queries = list()
        else:
            self.completed_queries = completed_queries

        if cancalled_queries is None:
            self.cancelled_queries = list()
        else:
            self.cancelled_queries = cancalled_queries

    def add_cancelled_query(self, query):
        '''
        cancel a query.
        :param query: a Query instance
        :type query: Query
        :return: None
        '''
        self.cancelled_queries.append(query)

    def add_waiting_query(self, query):
        '''
        Cancel a query.
        :param query: a Query instance
        :type query: Query
        :return: None
        '''
        self.waiting_queries[query.id] = query

    def add_serving_query(self, query):
        '''
        :param query: a Query instance
        :type query: Query
        :return: None
        '''
        self.waiting_queries.pop(query.id)

    def add_failed_query(self, query):
        '''
        :param query: a Query instance
        :type query: Query
        :return: None
        '''
        self.failed_queries.put(query)

    def add_completed_query(self, query):
        '''
        :param query:  a Query instance
        :type query: Query
        :return: None
        '''
        self.completed_queries.append(query)

    def dispatch_taxi(self, timestamp, query, database, taxi_set, road_network,
                      query_set):
        '''
        Respond to the query and try to dispatch a taxi for the query.

        :param timestamp: the current time of the simulation system
        :param query: the query
        :param database: the spatio-temporal database
        :param taxi_set: the taxi set
        :param road_network: the road network
        :param query_set:
        :type timestamp: int
        :type query: Query
        :type database: SpatioTemporalDatabase
        :type taxi_set: dict[int, Taxi]
        :type road_network: RoadNetwork

        :return: if the dispatch is successful or not
        :rtype: void
        '''
        #print("searching taxi_list")
        candi_taxi_list = self.dual_side_taxi_searching(
            timestamp, query, database, road_network, taxi_set)

        # if DEBUG_MODEL:
        #     if candi_taxi_list:
        #         print("candi_taxi_list successfully.......................taxi coming")
        #     else:
        #         print('candi_taxi_list failed..')

        if candi_taxi_list and self.__schedule(
                timestamp, query, candi_taxi_list, taxi_set, database,
                road_network, query_set):
            self.add_waiting_query(query)
            if DEBUG_MODEL:
                print(".............................satisfy the query ......")

            return True

        else:
            if DEBUG_MODEL and not candi_taxi_list:
                print "Failed: No taxi 000000000000000"
            self.add_failed_query(query)
            return False

        if DEBUG_MODEL:
            winsound.Beep(600, 1000)

    def dual_side_taxi_searching(self, timestamp, query, database,
                                 road_network, taxi_set):
        '''
        Dual_side taxi searching.
        :param timestamp: current time of the simulation
        :param query: the query
        :param database: the query
        :type timestamp: int
        :type query: Query
        :type database: sptioTemporalDatabase
        :return: a list of candidate taxis
        :type: list[int]
        '''
        o_grid = query.o_geohash
        o_candi_taxi_list = []
        d_grid = query.d_geohash
        d_candi_taxi_list = []
        candi_taxi_list = []

        #print("searching grid........")
        o_time_grid_list = self.grid_search(timestamp, query, True, database,
                                            road_network)
        d_time_grid_list = self.grid_search(timestamp, query, False, database,
                                            road_network)

        o_grid_list = [
            grid[0] for grid in database.grid[o_grid].spatial_grid_list
            if grid[0] in o_time_grid_list
        ]
        d_grid_list = [
            grid[0] for grid in database.grid[d_grid].spatial_grid_list
            if grid[0] in d_time_grid_list
        ]
        # print o_grid_list

        if DEBUG_MODEL and o_grid_list:
            print("o_grid_list successfully......."), len(o_grid_list)
            o_taxi_num = 0
            for grid_id in o_grid_list:
                o_taxi_num += len(database.grid[grid_id].taxi_list)
            print "Taxi num:", o_taxi_num

        if DEBUG_MODEL and d_grid_list:
            print("d_grid_list successfully......."), len(d_grid_list)
            d_taxi_num = 0
            for grid_id in d_grid_list:
                d_taxi_num += len(database.grid[grid_id].taxi_list)
            print "Taxi num:", d_taxi_num

        o_stop = False
        d_stop = False
        o_index = 0
        d_index = 0
        o_len = len(o_grid_list)
        d_len = len(d_grid_list)
        while not candi_taxi_list and (o_stop == False or d_stop == False):
            if o_index < o_len:
                o_tem_grid_id = o_grid_list[o_index]
                o_index += 1
                for o_tem_taxi in database.grid[
                        o_tem_grid_id].taxi_list:  #:type: taxi_list dict()
                    o_tem_time = database.grid[o_tem_grid_id].taxi_list[
                        o_tem_taxi]
                    #print len(database.grid[o_tem_grid_id].taxi_list), "....." , timestamp, "...", o_tem_time, "...",query.pickup_window.late
                    if o_tem_time < query.pickup_window.late:
                        o_candi_taxi_list.append(o_tem_taxi)
                    else:
                        break
            else:
                o_stop = True

            if d_index < d_len:
                d_tem_grid_id = d_grid_list[d_index]
                d_index += 1
                for d_tem_taxi in database.grid[d_tem_grid_id].taxi_list:
                    d_tem_time = database.grid[d_tem_grid_id].taxi_list[
                        d_tem_taxi]
                    if d_tem_time < query.delivery_window.late:
                        d_candi_taxi_list.append(d_tem_taxi)
                    else:
                        break
            else:
                d_stop = True

            if DEBUG_MODEL:
                print("......O_candi_taxi:"), len(o_candi_taxi_list)
                print("......d_candi-taxi:"), len(d_candi_taxi_list)
            candi_taxi_list = [
                val for val in o_candi_taxi_list if val in d_candi_taxi_list
            ]

        #print("..............index"), o_index,"/",len(o_grid_list), "......", d_index,"/",len(d_grid_list)
        if not candi_taxi_list:
            for taxi_id in o_candi_taxi_list:
                if not taxi_set[taxi_id].schedule:
                    candi_taxi_list.append(taxi_id)
        return candi_taxi_list

    def __schedule(self, timestamp, query, candi_taxi_list, taxi_set, database,
                   road_network, query_set):
        '''
        Taxi scheduling.

        The purpose of scheduling is to insert the origin and destination (ScheduleNode) of the query into the schedule
        of the taxi which satisfies the query with minimum additional travel distance.

        :param timestamp:
        :param query:
        :param candi_taxi_list: list[int]
        :param taxi_set: dict[int,taxi]
        :param database
        :param road_network:
        :param query_set:
        :return:
        '''
        if len(candi_taxi_list) == 0:
            return False

        min_taxi_o_index = -1
        min_taxi_d_index = -1
        min_taxi_increase = float('inf')
        min_taxi_load = float('inf')
        min_taxi_distance = 0
        min_matched_taxi_id = -1

        for taxi_id in candi_taxi_list:
            taxi = taxi_set[taxi_id]
            if not taxi.is_available():
                continue

            o_index = -1
            d_index = -1
            min_increase = float('inf')
            min_load = float('inf')
            cur_schedule_distance = taxi.schedule_distance
            matched_taxi_id = -1
            schedule_len = len(taxi.schedule)

            #computer the distance between schedule nodes
            dist_between_schedule = []
            for i in range(0, schedule_len - 1):
                dist_between_schedule.append(
                    get_shortest_path(
                        road_network, taxi.schedule[i].matched_vid,
                        taxi.schedule[i + 1].matched_vid).distance)

            for i in range(0, schedule_len + 1):
                for j in range(i + 1, schedule_len + 2):
                    taxi.schedule.insert(i, query.o_schedule_node)
                    taxi.schedule.insert(j, query.d_schedule_node)

                    [new_schedule_dist,
                     cur_load] = self.insertion_feasibility_check(
                         timestamp, query, i, j, database, taxi, road_network,
                         query_set, dist_between_schedule)
                    taxi.schedule.pop(j)
                    taxi.schedule.pop(i)

                    if 0 == cur_load:
                        continue
                    cur_increase = new_schedule_dist - cur_schedule_distance

                    if cur_increase < min_increase:
                        o_index = i
                        d_index = j
                        matched_taxi = taxi.id
                        min_increase = cur_increase
                        min_distance = new_schedule_dist
                        min_load = cur_load

            if min_increase < min_taxi_increase:
                min_taxi_o_index = o_index
                min_taxi_d_index = d_index
                min_matched_taxi_id = matched_taxi
                min_taxi_distance = min_distance
                min_taxi_load = min_load

        if min_matched_taxi_id == -1:
            # print "All taxis are...................44444444"
            return False
        else:
            query.matched_taxi = min_matched_taxi_id
            pick_taxi = taxi_set[query.matched_taxi]
            pick_taxi.schedule.insert(min_taxi_o_index, query.o_schedule_node)
            pick_taxi.schedule.insert(min_taxi_d_index, query.d_schedule_node)
            pick_taxi.update_route(road_network)
            pick_taxi.update_schedule_distance(min_taxi_distance,
                                               min_taxi_load)
            # print "o_index:%d   d_index:%d"%(min_taxi_o_index, min_taxi_d_index)
            # print "min_load:",min_taxi_load
            # print "taxi[%d]: %f"%(query.matched_taxi, pick_taxi.load)
            # print "schedule:", pick_taxi.schedule[0]
            # print "to-----:", pick_taxi.schedule[1]
            return True

    def grid_search(self, timestamp, query, isOrigin, database, road_network):
        '''
        To search candidate grid for a query
        :param timestamp: current time of system
        :param deadline: latest time of query ( pick/deliver)
        :param database: grid network of city
        :return:list[geohash]
        '''
        grid_list = []
        #compute pickup
        cur_geohash = query.o_geohash
        deadline = query.pickup_window.late
        if (isOrigin == False):
            cur_geohash = query.d_geohash
            deadline = query.delivery_window.late

        if DEBUG_MODEL:
            print "cur_geohash:", cur_geohash
        for grid in database.grid[cur_geohash].temporal_grid_list:
            # print "timestam:",timestamp,"   grid_2_grid:",grid[1],"     deadline:",deadline
            if timestamp + grid[1] <= deadline:
                grid_list.append(grid[0])
            else:
                break
        return grid_list

    def insertion_feasibility_check(self, timestamp, query, o_index, d_index,
                                    database, candi_taxi, road_network,
                                    query_set, dist_between_schedule):
        '''
        Return the distance and check the time constrain
        :param timestamp:
        :param query:
        :param o_index:
        :param d_index:
        :param database:
        :param candi_taxi:
        :param road_network:
        :param query_set:
        :return: distance of taxi.schedule
        '''
        # print len(candi_taxi.schedule)
        time_taxi_o = self.time_taxi_to_location(
            candi_taxi, query.o_schedule_node.matched_vid, road_network,
            database)
        if timestamp + time_taxi_o > query.pickup_window.late or candi_taxi.num_riders >= 4:
            return [0, 0]

        cur_vertex = -1
        min_dist = float('inf')

        pre_vertex_id = None
        total_dist = 0
        cur_load = 0
        flag_load = 0
        arrive_time = timestamp
        index_shedule_node = -1
        cur_riders = candi_taxi.num_riders
        for schedule_node in candi_taxi.schedule:
            # print "computing ......"
            index_shedule_node += 1
            # print "index:",index_shedule_node
            if schedule_node.is_origin:
                cur_riders += 1
                if cur_riders > candi_taxi.capacity:
                    # print ".......capacity constraint........"
                    return [0, 0]
            else:
                cur_riders -= 1
            if (index_shedule_node == 0):
                total_dist += get_distance(
                    candi_taxi.location,
                    road_network.get_vertex(
                        schedule_node.matched_vid).location)
                arrive_time = timestamp + total_dist / AVERAGE_SPEED

                if index_shedule_node == o_index:
                    flag_load += 1
            elif (index_shedule_node == o_index
                  or index_shedule_node == d_index):
                path = get_shortest_path(road_network, pre_vertex_id,
                                         schedule_node.matched_vid)
                arrive_time += path.distance / AVERAGE_SPEED
                total_dist += path.distance

                if flag_load % 2 == 1:
                    cur_load += path.distance
                flag_load += 1

            elif (index_shedule_node == o_index + 1
                  or index_shedule_node == d_index + 1):
                path = get_shortest_path(road_network, pre_vertex_id,
                                         schedule_node.matched_vid)
                arrive_time += path.distance / AVERAGE_SPEED
                total_dist += path.distance

                if flag_load % 2 == 1:
                    cur_load += path.distance
            elif (index_shedule_node > d_index):
                # print "taxi[%f]:  order=>%f"%(candi_taxi.id, candi_taxi.num_order)
                # print "len(schedule)---index:", len(candi_taxi.schedule), "  ", index_shedule_node
                # for node in candi_taxi.schedule:
                #     print node
                # print "len_dist_between_schedule:", len(dist_between_schedule)
                arrive_time += dist_between_schedule[index_shedule_node -
                                                     3] / AVERAGE_SPEED
                total_dist += dist_between_schedule[index_shedule_node - 3]
            elif (index_shedule_node > o_index):
                arrive_time += dist_between_schedule[index_shedule_node -
                                                     2] / AVERAGE_SPEED
                total_dist += dist_between_schedule[index_shedule_node - 2]

                cur_load += dist_between_schedule[index_shedule_node - 2]
            else:
                arrive_time += dist_between_schedule[index_shedule_node -
                                                     1] / AVERAGE_SPEED
                total_dist += dist_between_schedule[index_shedule_node - 1]

            # print "index:", index_shedule_node, "    dist:",total_dist
            # time.sleep(120)
            pre_vertex_id = schedule_node.matched_vid

            matched_query_id = schedule_node.query_id
            matched_query = query_set[matched_query_id]
            if schedule_node.is_origin:
                if arrive_time > matched_query.pickup_window.late:
                    # print "......pickup_window......"
                    return [0, 0]
            else:
                if arrive_time > matched_query.delivery_window.late:
                    # print "[%f, %f]---[%f,%f]"%(matched_query.pickup_window.early, matched_query.pickup_window.late, matched_query.delivery_window.early, matched_query.delivery_window.late)
                    # print "......deliver_window......",arrive_time
                    return [0, 0]

        return [total_dist, cur_load]

    def time_taxi_to_location(self, taxi, vertex_id, road_network, database):
        '''
        :param taxi: Taxi
        :param vertex: query.o_schedule_node.matched_vid/ query.d_schedule_nde.matched_vid
        :param road_network:
        :param database:
        :return: time from taxi to query.o_schedule_node/d_schedule_node
        '''
        #computer the distance from neareast vertex to taxi
        ver_id_2taxi = self.find_taxi_nearest_vertex(taxi, database,
                                                     road_network)
        ver_2taxi = road_network.get_vertex(ver_id_2taxi)
        taxi_vertex_dist = get_distance(ver_2taxi.location, taxi.location)

        # compute dist from vertex_neareast_taxi to vertex_neareast_loc
        dist_v2v = get_shortest_path(road_network, ver_id_2taxi,
                                     vertex_id).distance
        time_taxi_vertex = (taxi_vertex_dist + dist_v2v) / AVERAGE_SPEED

        return time_taxi_vertex

    def find_taxi_nearest_vertex(self, taxi, database, road_network):
        '''
        find the neareast vertex to the taxi
        :param taxi:
        :param database:
        :param road_network:
        :return: vertex_id
        '''
        neareast_vertex = -1
        min_dist = float('inf')
        for ver_id in database.grid[taxi.geohash].vertex_list:
            vertex = road_network.get_vertex(ver_id)
            dist = get_distance(taxi.location, vertex.location)
            if dist <= min_dist:
                neareast_vertex = ver_id
                min_dist = dist

        return neareast_vertex
Esempio n. 17
0
class Calc:
    """Calcualtor for evaluation different expressions"""

    def __init__(self):
        self.functions = {
            'EXP': Function(np.exp),
            'LOG': Function(np.log),
            'SIN': Function(np.sin),
            'COS': Function(np.cos),
            'SQRT': Function(np.sqrt)
        }
        self.operators = {
            'PLUS': Operator(np.add, 0),
            'ADD': Operator(np.add, 0),
            'TIMES': Operator(np.multiply, 1),
            'MULTIPLY': Operator(np.multiply, 1),
            'DIVIDE': Operator(np.divide, 1),
            'MINUS': Operator(np.subtract, 0),
            'SUBTRACT': Operator(np.subtract, 0)
        }

        self.output_queue = Queue()

    def calculate_expression(self, text):
        """Takes an expression in human readable form and calculates the answer"""
        text = self.parse_text(text)
        self.shunting_yard(text)
        answer = self.rpn()
        return answer

    def parse_text(self, text):
        """Parses human readable text into something that is ready to be sorted by shunting_yard"""
        text = text.replace(" ", "").upper()
        index = 0
        shunting_yard_ready = Queue()

        while index < len(text):
            text = text[index:]

            # Check for number
            match = re.search("^[-0123456789.]+", text)
            if match is not None:
                shunting_yard_ready.push(float(match.group(0)))
                index = match.end(0)
                continue

            # Check for function
            match = re.search("|".join(["^" + func for func in self.functions.keys()]), text)
            if match is not None:
                shunting_yard_ready.push(self.functions[match.group(0)])
                index = match.end(0)
                continue

            # Check for operator
            match = re.search("|".join(["^" + op for op in self.operators.keys()]), text)
            if match is not None:
                shunting_yard_ready.push(self.operators[match.group(0)])
                index = match.end(0)
                continue

            # Check for paranthases
            match = re.search("^[()]", text)
            if match is not None:
                shunting_yard_ready.push(match.group(0))
                index = match.end(0)
                continue

        return shunting_yard_ready

    def shunting_yard(self, elements: Queue):
        """Does the shunting yard algorithm to produce something that is ready for rpn"""
        operator_stack = Stack()
        while not elements.is_empty():
            element = elements.pop()

            if isinstance(element, numbers.Number):
                self.output_queue.push(element)
            elif isinstance(element, Function) or element == "(":
                operator_stack.push(element)
            elif element == ")":
                while operator_stack.peek() != "(":
                    self.output_queue.push(operator_stack.pop())

                # Pop (
                if operator_stack.peek() == "(":
                    operator_stack.pop()

                if not operator_stack.is_empty() and isinstance(operator_stack.peek(), Function):
                    self.output_queue.push(operator_stack.pop())
            elif isinstance(element, Operator):
                intermediate_storage = Stack()
                while ((not operator_stack.is_empty())
                       and (not operator_stack.peek() == "(")
                       and operator_stack.peek().strength < element.strength):
                    intermediate_storage.push(operator_stack.pop())

                while not intermediate_storage.is_empty():
                    operator_stack.push(intermediate_storage.pop())

                operator_stack.push(element)

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

    def rpn(self):
        """Evaluates self.output_queue in RPN"""
        intermediate_storage = Stack()
        while not self.output_queue.is_empty():
            item = self.output_queue.pop()
            if isinstance(item, numbers.Number):
                intermediate_storage.push(item)
            elif isinstance(item, Function):
                result = item.execute(intermediate_storage.pop())
                intermediate_storage.push(result)
            elif isinstance(item, Operator):
                operand1 = intermediate_storage.pop()
                operand2 = intermediate_storage.pop()
                result = item.execute(operand2, operand1)
                intermediate_storage.push(result)

        return intermediate_storage.pop()
Esempio n. 18
0
class Dispatcher:
    """A dispatcher fulfills requests from riders and drivers for a
    ride-sharing service.

    When a rider requests a driver, the dispatcher assigns a driver to the
    rider. If no driver is available, the rider is placed on a waiting
    list for the next available driver. A rider that has not yet been
    picked up by a driver may cancel their request.

    When a driver requests a rider, the dispatcher assigns a rider from
    the waiting list to the driver. If there is no rider on the waiting list
    the dispatcher does nothing. Once a driver requests a rider, the driver
    is registered with the dispatcher, and will be used to fulfill future
    rider requests.
    """
    def __init__(self):
        """Initialize a Dispatcher.

        @type self: Dispatcher
        @type _waitlist: Queue of Rider
        @type _fleet: PriorityQueue of Driver
        @rtype: None
        """
        self._waitlist = Queue()
        self._fleet = []

    def request_driver(self, rider):
        """Return a driver for the rider, or None if no driver is available.

        Add the rider to the waiting list if there is no available driver.

        @type self: Dispatcher
        @type rider: Rider
        @rtype: Driver | None

        >>> d = Dispatcher()
        >>> d1 = Driver('a', Location(9,0), 1)
        >>> d2 = Driver('b', Location(0,0), 1)
        >>> d._fleet = [d1, d2]
        >>> r1 = Rider('a', Location(0,0), Location(1,0), 3)
        >>> print(d.request_driver(r1))
        a
        """
        fastest_driver = self._fleet[0]

        for driver in self._fleet:
            if not driver.is_idle:
                self._waitlist.add(rider)
                return None
            else:
                for i in range(len(self._fleet) - 1):
                    for j in range(len(self._fleet) - 1):
                        if self._fleet[i].get_travel_time(rider.origin) \
                                < self._fleet[j].get_travel_time(rider.origin):
                            fastest_driver = self._fleet[i]
                        else:
                            fastest_driver = self._fleet[j]

        return fastest_driver

    def request_rider(self, driver):
        """Return a rider for the driver, or None if no rider is available.

        If this is a new driver, register the driver for future rider requests.

        @type self: Dispatcher
        @type driver: Driver
        @rtype: Rider | None

        >>> d = Dispatcher()
        >>> r1 = Rider('a', Location(0,0), Location(1,0), 3)
        >>> d._waitlist = Queue()
        >>> d._waitlist.add(r1)
        >>> d1 = Driver('a', Location(0,0), 1)
        >>> d2 = Driver('b', Location(0,0), 1)
        >>> d._fleet = [d1]
        >>> print(d.request_rider(d2))
        a
        >>> print(d._fleet)
        """
        if driver not in self._fleet:
            self._fleet.append(driver)

        # If waitlist is not empty, assign a rider
        if not self._waitlist.is_empty():
            return self._waitlist.remove()
        else:
            return None

    def cancel_ride(self, rider):
        """Cancel the ride for rider and change their status to CANCELLED.

        @type self: Dispatcher
        @type rider: Rider
        @rtype: None
        """
        rider._status = CANCELLED
        self._waitlist.remove(rider)
Esempio n. 19
0
class calculator:
    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),
            'SQUARE': Function(numpy.square)
        }

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

    def RPN(self):
        stack = Stack()
        while not self.output_queue.is_empty():
            ele = self.output_queue.pop()
            if isinstance(ele, float):
                stack.push(ele)
            elif ele in self.functions.keys():
                ele2 = stack.pop()
                stack.push(self.functions[ele].execute(ele2))
            elif ele in self.operators.keys():
                ele2 = stack.pop()
                ele3 = stack.pop()
                stack.push(self.operators[ele].execute(ele3, ele2))
        return stack.pop()

    def shunting_yard(self, string_regn):
        op_strong = "GANGE,DELE"
        op_stack = Stack()
        for ele in string_regn:
            if ele.isdigit() or ele[0] == '-':
                self.output_queue.push(float(ele))
            elif ele in self.functions.keys() or ele == "(":
                op_stack.push(ele)
            elif ele == ")":
                num = op_stack.pop()
                while num != "(":
                    self.output_queue.push(num)
                    num = op_stack.pop()
            if ele in self.operators.keys():
                peek = op_stack.peek()
                if peek:
                    if peek in op_strong:
                        self.output_queue.push(op_stack.pop())
                op_stack.push(ele)
            # print(op_stack.items)
            # print(self.output_queue.items)
        while not op_stack.is_empty():
            self.output_queue.push(op_stack.pop())
            # print(self.output_queue.items)
        return self.RPN()

    def string_parser(self, text):
        text.replace(" ", "")
        regex = '[-A-Z/(*/)*a-z0-9]+'
        #regex = '[-A-Za-z0-9]+'
        list1 = re.findall(regex, text)
        list3 = re.findall('[/(*/)*]+', text)
        list2 = []
        count_par = 0
        for i in list1:
            if '(' in i:
                num = i.count('(')
                self.split_par(i, list2, '(', num, list3, count_par)
                count_par += 1
            elif ')' in i:
                num = i.count(')')
                self.split_par(i, list2, ')', num, list3, count_par)
                count_par += 1
            else:
                list2.append(i)
        # print(list2)
        return self.shunting_yard(list2)

    def split_par2(self, i, list2, par, num):
        start_par = i.split(par)
        count = 0
        for ele in start_par:
            if ele != "":
                print(ele)
                list2.append(ele)
                for j in range(num):
                    list2.append(par)
                count += 2
        if count > len(start_par) + 1 + num:
            list2.pop(-1)
        return list2

    def split_par(self, i, list2, par, num, list3, count_par):
        start_par = i.split(par)
        count = 0
        for ele in start_par:
            if ele != "":
                list2.append(ele)
                for i in range(len(list3[count_par])):
                    list2.append(par)
                count += 2
        if count > len(start_par) + 1 + num:
            list2.pop(-1)
        return list2
Esempio n. 20
0
class Dispatcher:
    """A dispatcher fulfills requests from riders and drivers.

    When a rider requests a driver, the dispatcher assigns a driver to the
    rider. If no driver is available, the rider is placed on a waiting
    list for the next available driver. A rider that has not yet been
    picked up by a driver may cancel their request.

    When a driver requests a rider, the dispatcher assigns a rider from
    the waiting list to the driver. If there is no rider on the waiting list
    the dispatcher does nothing. Once a driver requests a rider, the driver
    is registered with the dispatcher, and will be used to fulfill future
    rider requests.
    """
    def __init__(self):
        """Initialize a Dispatcher.

        @type self: Dispatcher
        @type waiting_riders
        @type availalbe_drivers
        @rtype: None
        """

        self._available_drivers = []
        self._waiting_riders = Queue()

    def __str__(self):
        """Return a string representation.

        @type self: Dispatcher
        @rtype: str
        """

        return "Dispatcher:\n   waiting_riders {0}, \n  availalbe_drivers {1}"\
            .format(self._waiting_riders, self._available_drivers)

    def request_driver(self, rider):
        """Return a driver for the rider, or None if no driver is available.

        Add the rider to the waiting list if there is no available driver.
        If there are available drivers, return the one that can reach the driver fastest


        @type self: Dispatcher
        @type rider: Rider
        @rtype: Driver | None
        """

        if len(self._available_drivers) == 0:
            self._waiting_riders.add(rider)
            return None

        DriverTimes = []
        for driver in self._available_drivers:
            if driver.is_idle:
                DriverTimes.append(driver.get_travel_time(rider.origin))
        shortestTime = min(DriverTimes)

        for driver in self._available_drivers:
            if driver.get_travel_time(rider.origin) == shortestTime:
                return driver

    def request_rider(self, driver):
        """Return a rider for the driver, or None if no rider is available.

        If this is a new driver, register the driver for future rider requests.
        Return None if no riders are available, otherwise return the longest waiting rider.

        @type self: Dispatcher
        @type driver: Driver
        @rtype: Rider | None
        """

        if not driver in self._available_drivers:
            self._available_drivers.append(driver)

        if self._waiting_riders.is_empty():
            return None

        # The longest waiting rider if the first element of self.waiting_riders
        return self._waiting_riders.remove()

    def cancel_ride(self, rider):
        """Cancel the ride for rider.

        @type self: Dispatcher
        @type rider: Rider
        @rtype: None

        >>> John = Dispatcher()
        >>> Bobby = Rider('Bobby', Location(1,2), Location(3,4), 10)
        >>> John._waiting_riders.items = [Bobby]
        >>> John.cancel_ride(Bobby)
        >>> print(John._waiting_riders.items)
        []

        """

        if rider in self._waiting_riders.items:
            self._waiting_riders.items.remove(rider)
Esempio n. 21
0
class Calculator():
    def __init__(self):
        # Define the functions supported by linking them to Python
        # functions. These can be made elsewhere in the program,
        # or imported (e.g., from numpy)
        self.functions = {
            'EXP': Function(numpy.exp),
            'LOG': Function(numpy.log),
            'SIN': Function(numpy.sin),
            'COS': Function(numpy.cos),
            'SQRT': Function(numpy.sqrt)
        }
        # Define the operators supported
        # Link them to Python functions (here: from numpy)
        self.operators = {
            'PLUSS': Operator(numpy.add, 0),
            'GANGE': Operator(numpy.multiply, 1),
            'DELE': Operator(numpy.divide, 1),
            'MINUS': Operator(numpy.subtract, 0)
        }
        # Define the output−queue . The parse text method fills this with RPN.
        # The evaluate_output_queue method evaluates it
        self.output_queue = Queue()
        self.input_queue = Queue()

    def evaluate_output_queue(self):
        if not isinstance(self.output_queue.peek(),
                          Function) and not isinstance(
                              self.output_queue.peek(), Operator):
            raise TypeError("This is not RPN")

    def RSAcalculation(self):
        sta = Stack()
        size = self.output_queue.size()
        for i in range(0, size):
            element = self.output_queue.pop()
            if isinstance(element, numbers.Number):
                sta.push(element)
            elif isinstance(element, Function):
                number = sta.pop()
                sta.push(element.execute(number))
            else:  #element er operator
                number2 = sta.pop()
                number1 = sta.pop()
                sta.push(element.execute(number1, number2))
        return sta.pop()

    def to_RPN(self):
        op_stack = Stack()
        size_input = self.input_queue.size()
        for i in range(0, size_input):
            element = self.input_queue.peek()
            if isinstance(element, numbers.Number):
                self.output_queue.push(self.input_queue.pop())
            elif isinstance(element, Function):
                op_stack.push(self.input_queue.pop())
            elif element == "(":
                op_stack.push(self.input_queue.pop())
            elif element == ")":
                el = op_stack.peek()
                while el != "(":
                    self.output_queue.push(op_stack.pop())
                    el = op_stack.peek()
                op_stack.pop()
                self.input_queue.pop()
            elif isinstance(element, Operator):
                if not op_stack.is_empty():
                    el = op_stack.peek()
                    while (isinstance(el, Operator)
                           and el.strength >= element.strength) or isinstance(
                               el, Function):
                        self.output_queue.push(op_stack.pop())
                        if op_stack.is_empty():
                            break
                        el = op_stack.peek()
                op_stack.push(self.input_queue.pop())
        size_stack = op_stack.size()
        for i in range(0, size_stack):
            self.output_queue.push(op_stack.pop())

    def textparser(self, input_txt):
        txt = input_txt.replace(" ", "").upper()
        nums = "^[-0123456789.]+"
        funcs = "|".join(["^" + func for func in self.functions])
        ops = "|".join(["^" + op for op in self.operators])
        parenths = r"^[\(\)]"
        while txt != "":
            check = re.search(nums, txt)
            if check is not None:
                txt = self.sub_string(txt, check.end)
                self.input_queue.push(float(check.group(0)))
            check = re.search(funcs, txt)
            if check is not None:
                txt = self.sub_string(txt, check.end)
                self.input_queue.push(self.functions[check.group(0)])
            check = re.search(ops, txt)
            if check is not None:
                txt = self.sub_string(txt, check.end)
                self.input_queue.push(self.operators[check.group(0)])
            check = re.search(parenths, txt)
            if check is not None:
                txt = self.sub_string(txt, check.end)
                self.input_queue.push(check.group(0))

    def sub_string(self, string, end):
        if len(string) - 1 < end(0):
            return ""
        return string[end(0):]

    def calculate_expression(self, txt):
        self.textparser(txt)
        self.to_RPN()
        return self.RSAcalculation()
Esempio n. 22
0
class Dispatcher:

    def __init__(self,
                 failed_queries=None,
                 waiting_queries=None,
                 completed_queries=None,
                 cancelled_queries=None):
        """
        Initialize a Dispatcher.

        :param failed_queries: a Queue stores the queries that the dispatcher failed to find a taxi, these queries
        need to be processed in the next timestamp
        :param waiting_queries: a dict stores the queries that are dispatched a taxi and under waiting
        :param completed_queries: a list stores successfully completed queries
        :param cancelled_queries: a list stores cancelled queries
        :type failed_queries: Queue[Query]
        :type waiting_queries: dict[int, Query]
        :type completed_queries: list[Query]
        :type cancelled_queries: list[Query]
        :return: None
        """

        if failed_queries is None:
            self.failed_queries = Queue()
        else:
            self.failed_queries = failed_queries

        if waiting_queries is None:
            self.waiting_queries = dict()
        else:
            self.waiting_queries = waiting_queries

        if completed_queries is None:
            self.completed_queries = list()
        else:
            self.completed_queries = completed_queries

        if cancelled_queries is None:
            self.cancelled_queries = list()
        else:
            self.cancelled_queries = cancelled_queries

    def dispatch_taxi(self, timestamp, query, database, taxi_set, road_network):
        """
        Respond to the query and try to dispatch a taxi for the query.
        :param timestamp: the current time of the simulation system
        :param query: the query
        :param database: the spatio-temporal database
        :param taxi_set: the taxi set
        :param road_network: the road network
        :type timestamp: int
        :type query: Query
        :type database: SpatioTemporalDatabase
        :type taxi_set: dict[int, Taxi]
        :type road_network: RoadNetwork

        :return: if the dispatch is successful or not
        :rtype: void
        """

        candi_taxi_list = self.__single_side_search(timestamp, query, database)
        if self.__schedule(query, candi_taxi_list, taxi_set, road_network):
            self.add_waiting_query(query)
        else:
            self.add_failed_query(query)

    def add_cancelled_query(self, query):
        """
        Cancel a query.
        :param query: a Query instance
        :type query: Query
        :return: None
        """
        self.cancelled_queries.append(query)

    def add_waiting_query(self, query):
        """
        Cancel a query.
        :param query: a Query instance
        :type query: Query
        :return: None
        """
        self.waiting_queries[query.id] = query

    def add_serving_query(self, query):
        """
        :param query: a Query instance
        :type query: Query
        :return: None
        """
        self.waiting_queries.pop(query.id)

    def add_failed_query(self, query):
        """
        :param query: a Query instance
        :type query: Query
        :return: None
        """
        self.failed_queries.put(query)

    def add_completed_query(self, query):
        """
        :param query: a Query instance
        :type query: Query
        :return: None
        """
        self.completed_queries.append(query)

    @staticmethod
    def __single_side_search(timestamp, query, database):
        """
        Single-side taxi searching.

        :param timestamp: current time of the simulation system
        :param query: the query
        :param database: the spatio-temporal database
        :type timestamp: int
        :type query: Query
        :type database: SpatioTemporalDatabase
        :return: a list of candidate taxis
        :rtype: list[int]
        """

        o_grid = query.o_geohash
        candi_taxi_list = []

        for item in database.grid[o_grid].temporal_grid_list:
            if item[1] + timestamp > query.pickup_window.late:
                break

            grid_id = item[0]
            grid = database.grid[grid_id]

            # scan the taxi list of the grid and filter the taxis that satisfies the pickup time window
            for taxi_id in grid.taxi_list:
                eta = grid.taxi_list[taxi_id]  # arrival time of the taxi that comes into the gird in the near future
                if item[1] + eta <= query.pickup_window.late:
                    candi_taxi_list.append(taxi_id)
        return candi_taxi_list

    def __schedule(self, query, candi_taxi_list, taxi_set, road_network):
        """
        Taxi scheduling.

        The purpose of scheduling is to insert the origin and destination (ScheduleNode) of the query into the schedule
        of the taxi which satisfies the query with minimum additional travel distance.

        :param query: the query
        :param candi_taxi_list: list of taxi id
        :param taxi_set: the taxi set
        :param road_network: the road network
        :type query: Query
        :type candi_taxi_list: list[int]
        :type taxi_set: dict[int, Taxi]
        :type road_network: RoadNetwork
        :return: if the dispatch is successful or not
        :rtype: bool
        """
        if len(candi_taxi_list) == 0:
            return False

        picked_taxi_id = candi_taxi_list[0]
        min_dis = MAX_INT
        for taxi_id in candi_taxi_list:
            taxi = taxi_set[taxi_id]
            if not taxi.is_available():
                continue
            dis = get_distance(taxi.location, query.origin)
            if dis < min_dis:
                picked_taxi_id = taxi_id
                min_dis = dis

        picked_taxi = taxi_set[picked_taxi_id]
        query.matched_taxi = picked_taxi_id
        picked_taxi.schedule.append(query.o_schedule_node)
        picked_taxi.schedule.append(query.d_schedule_node)
        picked_taxi.update_route(road_network)

        return True
Esempio n. 23
0
class Calculator:
    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)
        }

        self.operators = {
            'ADD': Operator(numpy.add, 0),
            'PLUS': Operator(numpy.add, 0),
            'MULTIPLY': Operator(numpy.multiply, 1),
            'TIMES': Operator(numpy.multiply, 1),
            'DIVIDE': Operator(numpy.divide, 1),
            'SUBTRACT': Operator(numpy.subtract, 0),
            'MINUS': Operator(numpy.subtract, 0)
        }

        self.output_queue = Queue()
        self.input_queue = Queue()

    def evaluate(self):
        """
        ...
        """
        stack = Stack()
        for i in range(self.output_queue.size()):
            element = self.output_queue.pop()
            if isinstance(element, numbers.Number):
                stack.push(element)
            elif isinstance(element, Function):
                num = stack.pop()
                calculated_value = element.execute(num)
                stack.push(calculated_value)
            elif isinstance(element, Operator):
                num1 = stack.pop()
                num2 = stack.pop()
                calculated_value = element.execute(num2, num1)
                stack.push(calculated_value)
            else:
                raise Exception("Wrong type in the output_queue")

        if stack.size() != 1:
            raise Exception("Stack should be of size 1.")

        return stack.pop()

    def convert_queue_to_rpn(self):
        """
        ...
        """
        operator_stack = Stack()
        for i in range(self.input_queue.size()):
            element = self.input_queue.pop()
            if isinstance(element, numbers.Number):
                self.output_queue.push(element)
            elif isinstance(element, Function):
                operator_stack.push(element)
            elif element == "(":
                operator_stack.push(element)
            elif element == ")":
                while operator_stack.peek() != "(":
                    self.output_queue.push(operator_stack.pop())
                operator_stack.pop()
            elif isinstance(element, Operator):
                while operator_stack.size() != 0:
                    next_element = operator_stack.peek()
                    if isinstance(next_element, Operator):
                        if next_element.strength < element.strength:
                            break
                    elif next_element == "(":
                        break
                    self.output_queue.push(operator_stack.pop())
                operator_stack.push(element)
            else:
                raise Exception("Wrong type in input queue")

        for i in range(operator_stack.size()):
            self.output_queue.push(operator_stack.pop())

    def text_parser(self, text):
        """
        parse text with regex
        """
        text = text.replace(" ", "").upper()

        # Make match strings for regex
        functions = "|".join(["^" + func for func in self.functions.keys()])
        operators = "|".join(["^" + func for func in self.operators.keys()])
        parenthesis = "^[()]"
        nums = "^[-1234567890]+"

        while text != "":
            check_num = re.search(nums, text)  # Check if number
            if check_num is not None:
                matched_num = check_num.__getitem__(0)
                self.input_queue.push(float(matched_num))
                text = text[len(matched_num)::]
                continue

            check_par = re.search(parenthesis, text)  # Check if parenthesis
            if check_par is not None:
                matched_par = check_par.__getitem__(0)
                self.input_queue.push(matched_par)
                text = text[1::]
                continue

            check_op = re.search(operators, text)  # Check if operator
            if check_op is not None:
                matched_op = check_op.__getitem__(0)
                self.input_queue.push(self.operators[matched_op])
                text = text[len(matched_op)::]
                continue

            check_func = re.search(functions, text)  # Check if function
            if check_func is not None:
                matched_func = check_func.__getitem__(0)
                self.input_queue.push(self.functions[matched_func])
                text = text[len(matched_func)::]
                continue

        return self.input_queue

    def calculate(self, input_str):
        """
        Put everything together
        """
        self.text_parser(input_str)
        self.convert_queue_to_rpn()
        return self.evaluate()