Классы Python для простого приложения GTD

Я пытаюсь кодировать очень элементарное приложение GTD для себя, не только чтобы организоваться, но и лучше в кодировании и стать лучше в Python. У меня проблемы с классами.

Вот классы, которые у меня есть до сих пор:

class Project:
    def __init__(self, name, actions=[]):
        self.name = name
        self.actions = actions
    def add(self, action):
        self.actions.append(action)

class Action:
    def __init__(self, do='', context=''):
        self.do = do
        self.context = context

У каждого проекта есть свои действия, однако я хочу сделать так, чтобы проекты могли также состоять из других проектов. Скажем, ежедневно я хотел распечатать список всего. У меня возникли проблемы с тем, как мне составить список, который выглядел бы так

> Project A
>        Actions for Project A
>     Project B
>         Sub project A
>             Actions for Sub project A
>         Sub project B
>             Actions for Sub project B
>         Sub project C
>             Sub sub project A
>                 Actions for sub sub project A
>             Sub sub project B
>                 Actions for sub sub project B
>             Actions for Sub project C
>         Actions for Project B

Мне совершенно ясно, что будет использоваться рекурсия. Я борюсь с тем, чтобы создать другой класс с именем SubProject и подкласс Project для него. Что-то там просто заставляет мой мозг вызывать исключение.

Мне удалось взять проекты и добавить их к атрибуту действий в классе Project, однако затем я столкнулся с тем, где начинают появляться ситуации MegaProject.actions.action.actions.action.

Если бы кто-нибудь мог помочь со структурами классов, это было бы очень признательно!

3 ответа

Решение

Вы можете создать элемент подпроекта, аналогичный вашему списку действий, и назначить ему проекты аналогичным образом. Никакого подкласса проекта не требуется.

class Project:
    def __init__(self, name, actions=[], subprojects=[]):
        self.name = name
        self.actions = actions
        self.subprojects = subprojects

    def add(self, action):
        self.actions.append(action)

    def add_project(self, project)
        self.subprojects.append(project)

Более того, вы можете захотеть реализовать составной шаблон, где Projects являются составными, а Actions - листовыми.

class Project:
    def __init__(self, name, children=[]):
        self.name = name
        self.children = children

    def add(self, object):
        self.children.append(object)

    def mark_done(self):
        for c in self.children:
            c.mark_done()

class Action:
    def __init__(self, do):
        self.do = do
        self.done = False

    def mark_done(self):
        self.done = True

Ключевым моментом здесь является то, что проекты имеют тот же интерфейс, что и действия (за исключением методов добавления / удаления). Это позволяет рекурсивно вызывать методы на всем дереве. Если у вас была сложная вложенная структура, вы можете вызвать метод на верхнем уровне и отфильтровать его вниз.

Если вы хотите, чтобы метод получил плоский список всех конечных узлов в дереве (Actions), вы можете реализовать такой метод в классе Project.

def get_action_list(self):
    actions = []
    for c in self.children:
        if c.__class__ == self.__class__:
            actions += c.get_action_list()
        else:
            actions.append(c)
    return actions

Вы оценили существующие инструменты GTD? Я бы посмотрел на форматы файлов, используемые существующими инструментами GTD, особенно. те, которые сохраняются в XML. Это дало бы вам представление о том, какие способы организации данных такого типа имеют тенденцию работать.

Структура варьируется от довольно упрощенной (TaskPaper) до барочной (OmniFocus). Посмотри вокруг и узнай, что другие делали до тебя.

Я предлагаю вам взглянуть на составной шаблон, который можно применить к классу "Проект". Если вы сделаете свою структуру правильно, вы сможете сделать действие листом этого дерева, как вы описали в своем примере.

Вы можете, например, сделать класс Project (абстрактный), класс ProjectComposite (конкретный) и свой класс действий в виде листа.

Другие вопросы по тегам