Классы 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 (конкретный) и свой класс действий в виде листа.