在Taskpaper脚本中支持子任务

时间:2013-11-13 03:05:54

标签: python

首先,我对标题表示道歉,我不知道如何更具体地解决这个问题。我正在尝试创建一个脚本来收集下一行动列表(如在Getting Things Done方法中) )基于使用TaskPaper格式的整个Projects列表。这是将进入脚本的字符串类型的示例。

Inbox:

Project 01:
    - Task 01
    - Task 02
    - Task 03

Project 02:
    - Task 01
    - Task 02
    - Task 03
    - Task 04

我设法列出了我可以循环进入的主列表中的每个项目。这是我脚本的实际状态。请将arg[1]视为上述字符串:

allTasks = arg[1].split('\n\n')

projects = [filter(None,proj.split('\n')) for proj in allTasks]

next_actions = [task[:2] for task in projects if len(task) > 1]

变量next_actions将产生以下列表:[['Project 01:', '\t- Task 01'], ['Project 02:', '\t- Task 01']]这正是我想要的,但是,如果我向其中一个任务添加子任务,如下所示:

Project 01:
    - Task 01
        - Subtask 01
        - Subtask 02
        - Subtask 03
    - Task 02
    - Task 03

运行脚本,我的next_actions变量不会改变(我知道为什么,但我不知道如何解决它)。我希望结果是:[['Project 01:', '\t- Task 01\n\t\t- Subtask 01\n\t\t- Subtask 02\n\t\t- Subtask 03'], ['Project 02:', '\t- Task 01']]所以我可以支持子任务。也许早先用子任务识别任务并从中列出一个列表可以解决我的问题,但我不知道从哪里开始。

我是否遗漏了您需要的任何信息?请告诉我,我会尽快回复。谢谢你的帮助。

3 个答案:

答案 0 :(得分:2)

虽然远非优雅或可能是最佳方法,但我相信您应该利用嵌套数据结构来完成此任务。

给出以下任务字典:

t = {'Inbox':[],

    'Project 01': [
        ['Task 01',['subtask 1', 'subtask 2']],
        'Task 02',
        'Task 03'
    ],
    'Project 02':[
        ['Task 01',['subtask 1', 'subtask 2','subtask 3', 'subtask 4']],
        'Task 02',
        'Task 03',
        'Task 04'
    ]
}

此代码应该相对容易地处理具有子任务的下一个操作。

print "Next Actions"
for i in t:
    if len(t[i]) > 0:
        print "\n%s:" %i

        if isinstance(t[i][0], list):
            print "- %s" %(t[i][0][0])
            for st in t[i][0][1]:
                print "\t- %s" %(st)
        else:
            print t[i][0]

这将输出:

Next Actions

Project 01:
- Task 01
    - subtask 1
    - subtask 2

Project 02:
- Task 01
    - subtask 1
    - subtask 2
    - subtask 3
    - subtask 4

或者并使用您的初始列表和代码作为起点,您可以通过以下方式获得所需的结果。请注意,这将同时处理与下一个操作相关联的注释。

给出清单

t = '''Inbox:

Project 01:
    - Task 01
    this is a comment
    this is still a comment associate with task 01
        - sub 01
        - sub 02
        - sub 05
    - Task 02
    - Task 03
        - sub 03
        - sub 04

Project 02:
    - Task 01
        - proj 2 sub 01
    - Task 02
    - Task 03
    - Task 04'''

以下代码应该为您提供您所追求的结果。现在我只用有限的数据进行了测试,我确信应该有更优化的方法,但是现在这就是我所拥有的:

temp_list = {}
temp_sub = []
final_list = {}

allTasks = t.split('\n\n')
projects = [filter(None,proj.split('\n\t')) for proj in allTasks]

for i in projects:
    temp_list[i[0]]=i[1:]

for key,value in temp_list.iteritems():
    if len(value) > 0:
        temp_sub = []
        for s in range(1,(len(value)-1)):   
            if value[s].startswith('\t') or not value[s].startswith('-'):
                temp_sub.append(value[s])
            else:
                break
        final_list[key]=[value[0],temp_sub]

for key, value in final_list.iteritems():
    print key
    for sub in value:
        if len(value)>0 and len(sub)>0:
            if isinstance(sub, list):
                for item in sub:
                    print item
            else: 
                print sub

再一次,输出将是:

    Project 02:
- Task 01
    - proj 2 sub 01
Project 01:
- Task 01
this is a comment
this is still a comment associate with task 01
    - sub 01
    - sub 02
    - sub 05

现在,由于我们正在动态创建字典,您的最终结果(项目)将会松散顺序。我认为需要额外的代码来维持某种形式的排序。

答案 1 :(得分:1)

忽略之前的答案。我,像往常一样过于复杂的事情。这应该证明更简单,更短,同时仍能产生预期的效果。

来源列表

t = '''Inbox:

Project 01:
    - Task 01
    this is a comment
    this is still a comment associate with task 01
        - sub 01
        - sub 02
        - sub 05
    - Task 02
    - Task 03
        - sub 03
        - sub 04

Project 02:
    - Task 01
        - proj 2 sub 01
    - Task 02
    - Task 03
    - Task 04'''

<强>脚本

allTasks = t.split('\n\n')
projects = [filter(None,proj.split('\n\t')) for proj in allTasks]

for i in projects:
    if len(i[1:])>0:
        print i[0]
        print i[1]
        for s in range(2,len(i[1:])):
            if i[s].startswith("\t") or not i[s].startswith("-"):
                print i[s]
            else:
                break

<强>输出

Project 01:
- Task 01
this is a comment
this is still a comment associate with task 01
    - sub 01
    - sub 02
    - sub 05
Project 02:
- Task 01
    - proj 2 sub 01

使用较少的代码时,这也会保留项目的顺序。

答案 2 :(得分:1)

我使用re.split()

找到了一个合理的解决方案
re.split('\n(?=^\t-\s)', arg[1], 0, re.M)

作为arg [1]完整的任务串,此操作将在每个任务之前的换行符\n上拆分,该任务只有一个任务。考虑以下字符串:

Project 01:
    - Task 01
        - Subtask 01
        - Subtask 02
        - Subtask 03
    - Task 02
    - Task 03

上述re.split()将创建此列表:

['Project 01:', '\t- Task 01\n\t\t- Subtask 01\n\t\t- Subtask 02\n\t\t- Subtask 03', '\t- Task 02', '\t- Task 03']

之后,我可以在循环中使用project[:2]单独处理每个“项目”,以根据此问题的真实意图收集每个项目的下一个操作。谢谢你,佩德罗一直帮助我(: