Find a task by name.

        If a task with the exact name cannot be found, then tasks with similar
        names are searched for.

        Returns
        -------
        Task
            If the task is found.

        Raises
        ------
        NoSuchTaskError
            If the task cannot be found.

def find_task(self, name):
        """
        Find a task by name.

        If a task with the exact name cannot be found, then tasks with similar
        names are searched for.

        Returns
        -------
        Task
            If the task is found.

        Raises
        ------
        NoSuchTaskError
            If the task cannot be found.
        """

        try:
            return self.tasks[name]
        except KeyError:
            pass

        similarities = []

        for task_name, task in self.tasks.items():
            ratio = SequenceMatcher(None, name, task_name).ratio()
            if ratio >= 0.75:
                similarities.append(task)

        if len(similarities) == 1:
            return similarities[0]
        else:
            raise NoSuchTaskError(similarities)