我用一个简单的代码来组织我的todo.txt,其中包含Gina Trapani的语法,即上下文前面是@,项目前面是+,优先级标记为(A),(B )等。任务可以有多个上下文和项目。
我想要实现的是首先按上下文对行进行排序,并且在上下文块中,应该按项目排序,并且优先级的行首先出现在项目中。
我的代码到现在为止:
import os
import sys
import re
# Configuration
todo_path = notepad.getCurrentFilename()
def ordered_set(inlist):
out_list = []
for val in inlist:
if not val in out_list:
out_list.append(val)
return out_list
class Todo:
def __init__(self, priority, context, project, due, task, cdate):
self.__priority = priority
self.__context = context
self.__project = project
self.__due = due
self.__task = task
self.__cdate = cdate
def __len__(self):
return len(str(re.sub(' +',' ',str(self.__priority) +' '+' '.join(self.__context) + ' ' + ' '.join(self.__project) + ' ' + str(self.__due) + ' ' + str(self.__task) + ' ' + str(self.__cdate) + '\n')))
def priority(self):
return self.__priority
def context(self):
return self.__context
def project(self):
return self.__project
def due(self):
return self.__due
def task(self):
return self.__task
def cdate(self):
return self.__cdate
def BuildTodos():
global todos
todo_file = open(todo_path, 'r')
raw_todos = todo_file.readlines()
todo_file.close()
todos = []
for item in raw_todos:
item = item.strip("\n")
todos.append(item)
console.write("Loaded Todos\n")
for idx, item in enumerate(todos):
words = item.split(' ')
priority = [word for word in words if re.match('^\([A-Z]\)',word)]
context = [word for word in words if word.startswith('@')]
project = [word for word in words if word.startswith('+')]
due = [word for word in words if word.startswith('due:')]
task = [word for word in words if not re.match('^\([A-Z]\)',word) and not word.startswith('@') and not word.startswith('+') and not word.startswith('due:') and not re.match('[0-9]{4}-[0-9]{2}-[0-9]{2}',word)]
cdate = [word for word in words if re.match('[0-9]{4}-[0-9]{2}-[0-9]{2}',word)]
todos[idx] = Todo(priority, context, project, due, task, cdate)
console.write("Built Todos\n")
todos.sort(key=lambda t: t.context())
# ----------------
# HELP NEEDED HERE
# sort the lines by context and within the block of contexts lines should be
# ordered by projects and lines with priorities comes first in the project.
# ----------------
def OutTodos():
for t in todos:
console.write(re.sub(' +',' ',' '.join(t.priority()) + ' ' + ' '.join(t.context()) + ' ' + ' '.join(t.project()) + ' ' + ' '.join(t.due()) + ' ' + ' '.join(t.task()) + ' ' + ' '.join(t.cdate()) + '\n'))
console.clear()
BuildTodos()
OutTodos()
示例todo.txt文件,包含utf-8个字符(!):
(A) @personal +study +python organize todo.txt áőúíéá
(A) Schedule annual checkup +Health áőúíéá
(B) Outline chapter 5 +Novel @Computer áőúíéá
(C) Add cover sheets @Office +TPSReports áőúíéá
Plan backyard herb garden @Home áőúíéá
Pick up milk @GroceryStore áőúíéá
Research self-publishing services +Novel @Computer áőúíéá
Download Todo.txt mobile app @Phone áőúíéá
我在如何构建这种排序方面挤压我的想法,以便不以怪物结束。我的猜测是迭代todos列表,并且有级联ifs,但没有任何python中的排序/列表操作经验我会提出建议。
答案 0 :(得分:2)
我认为使用有序词典是前进的方法,这样你就可以将每行中的所有数据保存在一起,然后就可以搞清楚你想要它的打印方式。
dicts唯一的问题是他们总是需要一个密钥,因为你不总是提供一个上下文/项目/优先级。为了解决这个问题,我添加了' zzz'当没有可用时(这有助于排序,稍后将删除)。
我也遇到了你正在使用的.difference的问题,因为我认为它依赖于一个集合,即没有重复的数据,比如"这样做我想要"其中一个' to将被删除。
无论如何这里是代码(Python 2.7):
import re
import collections
import sys
fname = "todo.txt"
jobs = {}
myset = set()
#Recursive printing. Also orders the dictionary and removes zzz
def rprint(d):
a = collections.OrderedDict(sorted(d.items()))
for key, value in a.iteritems():
if isinstance(value, dict):
rprint(value)
else:
# check to see if the line is a repitition, this can occour
# when a line has more than one priority/project/context.
for line in value:
if line not in myset:
print str(line)
myset.add(line)
with open(fname) as f:
for line in f:
line = line.strip()
words = line.split(' ')
priority = [word for word in words if re.match('^\([A-Z]\)',word)]
context = [word for word in words if word.startswith('@')]
project = [word for word in words if word.startswith('+')]
#Need to make sure that there is always a key otherwise it will cause
#the dict issues, set key to zzz so that it will appear at the bottom when sorted
if not priority: priority = ["zzz"]
if not project: project = ["zzz"]
if not context: context = ["zzz"]
for i in context:
for j in project:
for k in priority:
if i not in jobs:
jobs[i] = {}
if j not in jobs[i]:
jobs[i][j] = {}
if k not in jobs[i][j]:
jobs[i][j][k] = []
jobs[i][j][k].append(line)
rprint(jobs)