コード例 #1
0
def depthFirstSearch(problem):
    """
    Search the deepest nodes in the search tree first.

    Your search algorithm needs to return a list of actions that reaches the
    goal. Make sure to implement a graph search algorithm.

    To get started, you might want to try some of these simple commands to
    understand the search problem that is being passed in:
    """
    root = problem.getStartState()
    rootNode = [root, []]
    if problem.isGoalState(root):
        return []

    frontier = Stack()
    frontier.push(rootNode)
    explored = []
    while not frontier.isEmpty():
        if problem.isGoalState(frontier.top()[0]):
            print("Found goal state")
            goal = frontier.pop()
            return goal[1]
        node = frontier.pop()
        if node[0] not in explored:
            explored.append(node[0])
            for child_state in problem.getSuccessors(node[0]):
                if child_state[0] not in explored:
                    child_path = node[1][:]
                    child_path.append(child_state[1])
                    frontier.push([child_state[0], child_path])
    return []
コード例 #2
0
class RESTServer(HTTPServer):
    def __init__(self, config, **kwargs):
        addr = ("", config["port"])
        super().__init__(addr, RequestHandler, **kwargs)

        self.endpoints = []
        self.plugins = []
        self.load_plugins()

        self._endpoints_to_register = None
        self._errors = Stack()
        self._error_lock = Lock()

        logging.info("Running server.")
        try:
            self.serve_forever()
        except KeyboardInterrupt:
            self.shutdown()

    def load_plugins(self):
        # import
        for el in pkgutil.iter_modules([PLUGINDIR]):
            plugin = el[1]
            try:
                p = pkgutil.importlib.import_module("{}.{}".format(
                    PLUGINDIR, plugin))
            except Exception as e:
                logging.error("Unable to load plugin: {} ({})".format(
                    plugin, e))
                continue
            else:
                self.plugins.append(p)

        # load
        failed = []
        for i in range(len(self.plugins)):
            module = self.plugins[i]
            try:
                self._endpoints_to_register = []
                plugin = module.Plugin(self)
                logging.info("Loaded Plugin: {}".format(plugin.name))
            except (AttributeError, TypeError, Exception) as e:
                failed.append(module)
                logging.error("Unable to load plugin: {} ({})".format(
                    module, e))
                continue

            self.plugins[i] = plugin
            for endpoint in self._endpoints_to_register:
                self.endpoints.append((endpoint, plugin))
                logging.info("Registered endpoint: {}".format(endpoint.path))
            self._endpoints_to_register = None

        for el in failed:
            self.plugins.remove(el)

    def match_endpoints(self, path):
        """
        Finds the endpoint that matches best with path.
        If path is "/a/b/c", it matches "/a/b" better than "/a". It does not match "/b".
        :param path: path that is to be matched
        :return: endpoint object that matches; None if no match is found
        """
        path = sanitize_path(path).split("/")
        candidates = []
        for el in self.endpoints:
            candidates.append(el[0])
        matches = []
        todel = []

        # comparison loop
        for i in range(len(path)):
            if not candidates:
                break
            for el in candidates:
                if len(el.pathlist) == i:
                    matches.append(el)
                    todel.append(el)
                elif el.pathlist[i] != path[i]:
                    todel.append(el)
                elif i == len(el.pathlist) - 1:
                    matches.append(el)

            for el in todel:
                candidates.remove(el)
            todel = []

        if not matches:
            return None

        # get best match
        best = matches[0]
        for el in matches:
            if len(el.pathlist) > len(best.pathlist):
                best = el
        return best

    def register_endpoint(self, endpoint):
        """
        Registers and endpoint.
        :param endpoint: Endpoint object
        """
        if self._endpoints_to_register is None:
            logging.error(
                "Endpoints must be registered in the Plugin constructor ({})".
                format(endpoint.path))
            return
        if endpoint not in self.endpoints and endpoint not in self._endpoints_to_register:
            self._endpoints_to_register.append(endpoint)
        else:
            logging.error("Endpoint already registered: {}".format(
                endpoint.path))

    def report_error(self, endpoint, msg, timestamp=None):
        """
        Reports an error to the server error stack.
        :param endpoint: Endpoint object the error occured in.
        :param msg: Error message.
        :param timestamp: Error timestamp; uses now if ommited.
        :return:
        """
        error = Error(endpoint, msg, timestamp)
        self._error_lock.acquire()
        self._errors.push(error)
        self._error_lock.release()

    def consume_errors(self):
        """
        Generator for all errors on the server error stack. Errors are removed from the stack (popped).
        """
        self._error_lock.acquire()
        while True:
            try:
                yield self._errors.pop()
            except IndexError:
                break
        self._error_lock.release()

    def consume_error(self):
        """
        Pops one error from the server error stack (read and remove).
        :return: Last error
        """
        self._error_lock.acquire()
        r = self._errors.pop()
        self._error_lock.release()
        return r

    def has_error(self):
        return not self._errors.is_empty()

    def last_error(self):
        """
        Reads the last error from the error stack. Does not remove it.
        :return: Last error
        """
        self._error_lock.acquire()
        r = self._errors.top()
        self._error_lock.release()
        return r

    def shutdown(self):
        for plugin in self.plugins:
            try:
                plugin.shutdown()
            except AttributeError:
                logging.info(
                    "Plugin {} has no shutdown method.".format(plugin))
                pass
            except Exception as e:
                logging.error("Plugin {} failed to shut down ({})".format(
                    plugin, e))

        logging.info("Shutting down.")
        try:
            self.shutdown()
        except Exception as e:
            logging.error("Clean shutdown failed ({})".format(e))