tag:blogger.com,1999:blog-224314782024-03-14T11:52:22.276+08:00DummyDigit@Blogger/随机数字终端Random digit output from dummy computer... you really believe it?Anonymoushttp://www.blogger.com/profile/01776840235317220202noreply@blogger.comBlogger16125tag:blogger.com,1999:blog-22431478.post-16403932918697384002012-05-01T14:20:00.000+08:002012-05-01T14:21:25.410+08:00A quick comparison between Readability and PocketTo be honest, I'm not really a hard-core tech. fashion follower. That's why I heard of <a href="http://getpocket.com/">Pocket</a> and <a href="http://www.readability.com/">Readability</a> just a few days ago. I downloaded both app to my Motorola Defy (Cyanogen Mod 9 nightly buids) and registered accounts. Then I used them for days.<br />
<br />
Feeling? See below:<br />
<br />
<b>Adding entries: Pocket > Readability.</b><br />
Both Readability and Pocket support adding post from Browser. Pocket uses an snippet of Javascript code, which can be saved to bookmark list. Readability recommends I install a plug-in, which supports Safari, Firefox and Chrome. By the way, it looks like there's no plug-in for IE. Does Readability team decide to remove the support for IE? Kindly correct me if I'm wrong.<br />
<br />
I personally like Pocket's way a little bit more. Installing a plug-in is not always working when user need to use a shared computer (like me). Pocket's solution is simpler, and working for almost all browsers.<br />
<br />
In my Android phone (Motorola Defy), the story is a little bit different. Both two apps provides "share to ..." for sharing. The difference is the UI response: Pocket is always pops an quick on-screen message fast, while Readability's sharing button has no response until several seconds after. Another problem is Readability sometimes pops up a "adding article fails" message so I have to share it again, while Pocket never fails me.<br />
<br />
NOTE: As a man lives in Great Fire Wall, I can't confirm if Readability should be responsible for the last problem.<br />
<br />
<b>Sync: Pocket >>> Readability.</b><br />
I'll say this is the most important reason I like Pocket. In the environment of using my China Unicom ADSL connection, a new post can be seen immediately in Pocket. Meanwhile, I have to wait for a while (probably 2 - 3 minutes) to see it appear in Readability reading list.<br />
<br />
Frankly speaking, this issue may not be a deal break: why do I want to see an entry in list when I has already decided to read it later?<br />
<br />
I think it's just because of perfection. Who knows?<br />
<br />
<b>Page re-formatting: Readability >> Pocket.</b><br />
Readability wins. With multiple reading theme and clear font settings, the reading experience is more comfortable. Meanwhile, Pocket only allows switching fonts by clicking the same button for several times, which is not intuitive to me.<br />
<br />
Add-on for Chinese. One difference between Readability and Pocket for Chinese character is Readability does not use Italic fonts for Chinese characters, while Pocket uses it. Though I personally believe this is a bug, I must say thanks to Readability. This is because Chinese does not use italic at all. As for Pocket, the use of italic fonts makes Chinese articles looks weird.<br />
<br />
<br />
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<b>Night reading mode: Readability >> Pocket.</b></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
In one word, I hate the night reading theme from Pocket! There's only one pure black theme for Pocket and it looks ugly. Readability is much better: it offers five themes (wheat, black, light blue, etc.) to allow me choose proper theme for different environments. The most remarkable point is Readability uses a dark grey background for night reading theme, instead of pure black. That makes my eyes much comfortable. My taste, at least.</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<br /></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<b>Subscribing: Readability > Pocket. (You may have different point of view)</b></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
Readability offers a subscribing mode, which charges us a small amount to support article writers, $5/month. The 70% of the money will go to the article writers. I didn't see equivalent approaches in Pocket.</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<br /></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
Some people may not like it. As for me, I'm fine because I'm always happy to support my favorite writers. So that depends on you. At least, you may choose to decline this without losing any features from Readability.</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<br /></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<b>App memory usage: Both are bad :(.</b></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
Well, when saying memory usage, I mean Android. Both apps uses 35+MB memory, which eats a huge block of memory. When I keep both open, my poor phone becomes slow because memory is swapping in and out.</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<br /></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
Conclusion? Not yet.</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<br /></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
I want to try more, as I'm still new to both services. Moreover, I don't know if I should recommend you guys use them in phone. I personally prefer Evernote if I want to keep an article. If I want to read an article later (and in a cleaner format), I like computer. Anyway, let me try it a little bit more before making a conclusion. I'll keep you updated.</div>
<div>
<br /></div>Anonymoushttp://www.blogger.com/profile/01776840235317220202noreply@blogger.com17tag:blogger.com,1999:blog-22431478.post-13197015487776542432012-03-05T15:47:00.001+08:002012-03-05T15:58:13.630+08:00A quick script to convert your BASH environment settings to environment.plistWhen a new Linux guy who switchs to Mac, the first problem for them to use environment.plist. Here's a simple example to convert environment settings to environment.plist. This is especially true when the project you work with uses a lot of environment settings in your XCode project file.<br />
<br />
So I created the script below to help me sort it out. It is not a complete script to handle all special cases like differences between ${} and $ token in BASH, but already good enough in my environment.<br />
<br />
Try modify code yourself and enjoy hacking!
<br />
<br />
<pre>#!/usr/bin/env python
import sys
import re
keyval_pat = re.compile(r"[ ]*export ([^=]*)=(.*)")
fd = open(sys.argv[1])
print(r'<?xml version="1.0" encoding="utf-8">')
print(r'''
<!DOCTYPE plist PUBLIC
"-//Apple DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">''')
print('<plist version="1.0">')
print('<dict>')
for each_line in fd:
m = keyval_pat.search(each_line)
if m is None:
continue
key = m.group(1)
value = m.group(2)
print("<key>%s</key><string>%s</string>" % (key, value))
print('</dict>')
print('</plist>')
fd.close()
</pre>Anonymoushttp://www.blogger.com/profile/01776840235317220202noreply@blogger.com1tag:blogger.com,1999:blog-22431478.post-55527271738370044972012-02-25T00:07:00.002+08:002012-02-25T00:07:49.955+08:00DummyDigit, ReloadedIt has been a long time since my last blog post was out. Sorry for keeping silent for such a long time.<div>
<br /></div>
<div>
There were so many things happened from 2010 to 2011. Quite a bit. My girlfriend broke up with me. I dropped my job in US and moved back to Beijing. I broke up with my girlfriend (nah you know the difference, buddy). I lost my job (the whole team was cancelled) and got the second offer to went back to US. I found my new love and decided to stay. I got a second job and declined the offer.</div>
<div>
<br /></div>
<div>
Crazy, huh?</div>
<div>
<br /></div>
<div>
Anyway, just like everyone says, thing always becomes better. Though I'm really missing my friends in Washington, I decided to stay in Beijing with my girl for a while. Meanwhile, it's also the time to make this Blog active again.</div>
<div>
<br /></div>
<div>
I'm back, my friends.</div>Anonymoushttp://www.blogger.com/profile/01776840235317220202noreply@blogger.com0tag:blogger.com,1999:blog-22431478.post-49727612853902389832010-02-28T17:03:00.000+08:002010-02-28T17:03:18.021+08:00TaggyTODO:该不该添加周期性任务支持?很长时间没有更新TaggyTODO了。这期间发生了很多事情,有个人的,也有工作上的,导致实在没有时间。但最主要的问题是设计上的,因为我正在考虑一个重要功能,而这个功能最终可能导致整个设计的大幅改变,我不敢不慎重。<br />
<br />
这个功能就是周期任务支持。<br />
<br />
我一直很犹豫是不是需要让TaggyTODO支持周期性任务,因为这个东西实在非常有诱惑力。很多我们生活中的任务都是周期性质的,比如每个月的水电费,支付信用卡帐单,话费,等等。<br />
<br />
但是周期性任务的支持会带来的设计上的巨大变化。首先是我们如才能合理地定义多个任务。有一个很简单的方法是:一个任务需要重复多少次,我们就在数据库里保留多少个任务。这个设计是最简单也最容易实现的,但这一来有一个问题:假如用户要求无限重复怎么办?例如用户试图定义一个任务,记录每个月的水电费缴纳情况。假如他/她已经买了房子,那么这个任务可以一直持续到他/她把房子卖掉的时候。我总不能添加无数个任务对象。退一步讲,即使我们限制了重复的最大次数,比如最多365项,那么用户定义一个每天的任务就需要占用365个项目,任务一多起来就会迅速地占用数据库的大量空间,我个人认为这个很难接受。<br />
<br />
<br />
另一个方案是只定义一个任务,但通过内部添加一些数据来表示和记录多个重复事件的完成情况,每个任务可以通过当前日期计算出相应的起止时间。这个方案就可以有效地节约空间占用问题,但存在一个缺点:假如用户备份并删除了一个老任务,那么后来应当发生的新任务就给一并删掉了。另一个需要解决的问题是如何处理临时改期。对第一个方案这不是问题,而对这个方案来说则需要添加一个新事件,那么如何关联两个事件?这也是需要解决的。<br />
<br />
<br />
当然,一个最直白的手段是:我不支持重复事件,简单而直接。事实上很多我见到的任务管理程序就是这么做的。不过我还是希望给自己一点挑战。<br />
<br />
先记录到这里吧。Anonymoushttp://www.blogger.com/profile/01776840235317220202noreply@blogger.com0tag:blogger.com,1999:blog-22431478.post-31151835791286175302009-12-28T08:30:00.000+08:002009-12-28T09:00:48.674+08:00TaggyTODO:工作模型(三) 任务分类标题更新:Gotask正式更名为TaggyTODO。<br />
<br />
<br />
我对任务分类的考虑相当简单,就一条:tag。每一个TaggyTODO中的任务都可以被打上一个或多个标记,比如“家庭事务”,“工作”,“重要”,“可以忽略”。每当定义一个新的任务时,用户可以选择打上对应的标记。在后来查询的时候我们就可以利用这些标记过滤出我们要的任务,比如“所有可以忽略的工作事务”,或“重要的家庭事务”。我知道很多管理程序都喜欢在tag之外再实现一个能包含层级关系的category概念用于分类,但我不打算这么干,因为我认为tag本身已经足够用于表示分类,至于层级关系,我认为可以用tag组合代替,不需要多此一举。<br />
<br />
必须强调的是,我希望tag是必须先定义后使用的。这一点和通常意义上的tag不同。如今我见过的很多用tag这个概念的软件一般都是允许用户随意增减tag的,比如Blogger,每一篇文章都能随便加个标记,Blogger会记录所有用到过的标记,并只显示目前仍在被使用的。但是我认为随意定义tag的做法不适合管理任务,因为用户可能会定义一堆实际意义相同而叫法不同的标记,然后在最后定义query的时候发现自己顾此失彼,总是漏掉一两个任务。<br />
<br />
我更期望一个tag应该是一个有限的集合。用户用之前就定义好,需要的时候从列表中选择。这样用户能更仔细地定义所有的tag,因此任务的标记信息可以更规范。除此之外,预先定义还有一个额外的好处:当用户发现某个tag名字不合理时不用一个个任务修正,只需要修改那个tag定义本身就可以了。——别忘了TaggyTODO的目标是用来管理大数量的长期任务,要求用户一个个修改任务可不是什么聪明主意。<br />
<br />
最后,我不打算提供任务名称中关键字搜索的功能,也就是说,查询任务时tag是除时间之外唯一的搜索条件。我知道也许有人会认为这种做法太死板,特别是Outlook的用户,他们往往更习惯于在search框里输入标题中的关键字来查找。但我认为我的考虑更适合TaggyTODO,理由有两个:<br />
<ul><li>概念单一不会使用户养成不同的使用习惯。假定我同时提供标题字符串搜索和tag,就可能出现两个用户一个习惯用tag而另一个习惯搜索标题的情况。如果他们两人共享任务列表,则合并后的task就无法满足任何一个人的需要。</li>
<li>基于tag查找的方法进行优化的方法简单。单纯字符串搜索就可能得动用索引结构之类的大家伙了。相比之下,我更希望我的软件能尽量小一点。</li>
</ul>当然,TaggyTODO相对于邮件程序而言更容易实现分类规范化。因为所有的任务定义都是从用户这边来的。邮件程序必须使用字符串搜索的理由是用户收到的邮件来自四面八方,我们不可能要求所有联系人都用一样的规范写信。相比之下,都是自己定义的任务就不会有这个问题。Anonymoushttp://www.blogger.com/profile/01776840235317220202noreply@blogger.com0tag:blogger.com,1999:blog-22431478.post-75640827541071560102009-12-28T07:43:00.000+08:002009-12-28T07:45:35.964+08:00First Release: GoTask is renamed as TaggyTODO!OK. So I finally pushed the first bunch of code for GoTask to Google Code. It's still incomplete, which can only run some basic unit tests, but I'll update in the new year. -- New year, new start, right? :)<br />
<br />
Also, I finally found a name for the project: <span style="font-size: small;"><b><span style="font-family: "Courier New",Courier,monospace;">TaggyTODO</span></b></span>. I have to change the name because I found the name GoTask has been used in another project, a library for Game development. Hope the name is not used again.<br />
<br />
If you are interested in it, check it out from <a href="http://code.google.com/p/taggytodo">http://code.google.com/p/taggytodo</a>.Anonymoushttp://www.blogger.com/profile/01776840235317220202noreply@blogger.com0tag:blogger.com,1999:blog-22431478.post-87867860144295459102009-12-23T17:20:00.000+08:002009-12-23T17:29:17.512+08:00ConsoleKit, access denied and a see-it-once bug I just noticed an interesting bug when I upgraded my ArchLinux last Sunday. Every time when I log on my Openbox desktop, I found my NetworkManager applet icon cannot be shown on the system tray. When I invoke nm-applet from comman line, I got an error like below: <br />
<br />
<blockquote><pre>** (nm-applet:14122): WARNING **: <warn> applet_dbus_manager_start_service():
Could not acquire the NetworkManagerUserSettings service.
Message: 'Connection ":1.21" is not allowed to own the service
"org.freedesktop.NetworkManagerUserSettings" due to security policies in the
configuration file'
</warn></pre></blockquote>The most interesting thing is: the issue only happens *once*. When I log out and log in again, everything looks fine.<br />
<br />
Obviously it's not a hardware issue. Since it only happens after upgrading, I decided to have a check on udev configuration files and finally got something new:<br />
<br />
<blockquote><span style="font-size: xx-small;"><policy at_console="true"></span><br />
<span style="font-size: xx-small;"> <allow own="org.freedesktop.NetworkManagerUserSettings"/></span><br />
<span style="font-size: xx-small;"> <allow send_destination="org.freedesktop.NetworkManagerUserSettings"</span><br />
<span style="font-size: xx-small;"> send_interface="org.freedesktop.NetworkManagerSettings"/></span><br />
<span style="font-size: xx-small;"> <allow send_destination="org.freedesktop.NetworkManagerUserSettings" send_interface="org.freedesktop.NetworkManagerSettings.Connection"/> </span><br />
<span style="font-size: xx-small;"> </policy></span></blockquote><br />
This is new to me. I know that the traditional way is to use network group to define who can access network configuration. I also got some suggestions from <a href="http://wiki.archlinux.org/index.php/NetworkManager">*here*</a> that I should add <policy group="network"> to make it back to old behavior.<br />
</policy><br />
<br />
But wait -- is it really the root cause? If that is the case, why it works when I log on twice?<br />
<br />
After some studies I noticed that the settings above are used by ConsoleKit. Meanwhile, I also found that there should be a daemon, /usr/sbin/console-kit-daemon, which will assign an XDG_SESSION_COOKIE environment variable to every active logon session so it can determine who is using the current console. This is important for nm-applet to determine who should be assigned the access to read network settings.<br />
<br />
Look -- the key is here. I didn't see XDG_SESSION_COOKIE environment variable when I log on system for the first time! However, I'm able to see the setting from the second logon. It seems the server was not there but was then invoked after first session, but NO DOCUMENT says that console-kit-daemon can be automatically started!<br />
<br />
So the final fix is rather simple: I opened my /etc/rc.local file and added two lines:<br />
<blockquote style="font-family: "Courier New",Courier,monospace;">#!/bin/bash<br />
/usr/sbin/console-kit-daemon<br />
</blockquote>That will force starting a console-kit-daemon service when system starts up. I rebooted the machine and everything works then.<br />
<br />
Also, it just solve another see-it-once issue: my PCManFM file manager always give me an error when I'm trying to mount any USB flash disk, with a message like "send message rejected". This is also a see-it-once issue on my first logon session. After applying the fix (or workaround? Who knows) above, it also disappeared.<br />
<br />
So my friend, if you are also experiencing the same issue, try that. Good luck.Anonymoushttp://www.blogger.com/profile/01776840235317220202noreply@blogger.com0tag:blogger.com,1999:blog-22431478.post-19817604001540204252009-11-20T16:01:00.000+08:002009-12-28T07:46:05.990+08:00Gotask:设计部分暂停简单地说,四个原因:<br />
<br />
a) 最近工作实在太忙,脱不开身。<br />
b) 最近是人生一个重大转折,不可不上心。<br />
c) Gotask可能要改名。<br />
d) 光说不练,假把式。<br />
<br />
这一个多月我也没闲着,目前的状态是Gotask的查询部分代码已经完成,正在开始写XML解析和数据库的部分。如今暂定的计划是年内能够发布查询和数据库部分的函数库代码,而后续的设计我希望留到至少开始UI部分再开始。<br />
<br />
另外,Gotask使用的开发语言是Python(>= 2.5),暂时没有做C扩展的方案。目前的计划是在数据库和查询的部分实现Python2和Python3双兼容,UI部分第一个实现应当会基于GTK+。Anonymoushttp://www.blogger.com/profile/01776840235317220202noreply@blogger.com0tag:blogger.com,1999:blog-22431478.post-60903081882345144672009-10-08T10:45:00.000+08:002009-12-28T07:38:05.000+08:00What a *Great=Fire=Wall*!I just noticed that I haven't updated my blog for such a long time.<br />
<br />
Now I'm in Beijing with my girlfriend (I love her, yes, I'm serious) and got a problem: I can hardly access my blog even with Tor. Thanks to the *Great=Fire=Wall*, it even blocks the global public Tor server list. :)<br />
<br />
Fortunately, we still have bridges as the last weapon, but I'd better use it as less as possible. I'll update the blog for GoTask when I'm back to US.<br />
<br />
To all bridges providers -- I just want to say sorry for using your bandwidth without sharing mine. This is because I'm living in a hotel right now and cannot freely use the connection.Anonymoushttp://www.blogger.com/profile/01776840235317220202noreply@blogger.com0tag:blogger.com,1999:blog-22431478.post-57816870782269501422009-09-06T04:31:00.000+08:002009-12-28T08:33:14.252+08:00My Python Gochas: Non UTF Encoding support does not always work As claimed by a lot of tutorials, <a href="http://www.python.org/">Python</a> is well known to be a very good platform for manipulating XML. Yeah it's true, however there is a trap waiting for you. <br />
<br />
Comparing with other XML APIs, such as MSXML or IBM's Xcerces-C, the default Python XML APIs (xml.dom, etree, or even PyXML) does not provide full supports for multiple encodings. For example, if you comes from China, you might want to encode your document in GB2312/GBK or BIG5. However, you might receive some information like below when you are parsing it (tried on Python 2.6.2) :<br />
<blockquote><span style="font-family: "Courier New",Courier,monospace;"><br />
<?xml version="1.0" encoding="GB2312"?><br />
<hello>world</hello><br />
</span><br />
</blockquote><blockquote style="font-family: "Courier New",Courier,monospace;">import xml.dom.minidom<br />
xml.dom.minidom.parse('test.gbk.xml')<br />
Traceback (most recent call last):<br />
File "", line 1, in <br />
File "/usr/lib/python2.6/xml/dom/minidom.py", line 1918, in parse<br />
return expatbuilder.parse(file)<br />
File "/usr/lib/python2.6/xml/dom/expatbuilder.py", line 924, in parse<br />
result = builder.parseFile(fp)<br />
File "/usr/lib/python2.6/xml/dom/expatbuilder.py", line 207, in parseFile<br />
parser.Parse(buffer, 0)<br />
xml.parsers.expat.ExpatError: unknown encoding: line 1, column 30<br />
</blockquote><br />
It's confusing to most of the Python newbies because the document above is actually a valid XML document. It's also surprising because python itself can correctly handle GB2312 since python 1.6.<br />
<br />
But my friend, don't just start complaining: Python does nothing wrong.<br />
<br />
The strange behavor comes from the library. Python uses <a href="http://expat.sourceforge.net/">Expat</a> as the implementation of almost all XML libraries. Currently Expat supports very limited encodings: US-ASCII, UTF-8, UTF-16, and ISO-8859-1 (If you are working on Linux/UNIX, check man page of <span style="font-family: "Courier New",Courier,monospace;">xmlwf</span> tool). However, it is compliant with <a href="http://www.w3.org/TR/xml/#charsets">XML standard, section 2.2</a>:<br />
<blockquote style="font-family: "Courier New",Courier,monospace;"><br />
<a href="http://www.blogger.com/post-edit.g?blogID=22431478&postID=5781687078226950142">The mechanism for encoding character code points into bit patterns may vary from entity to entity. All XML processors MUST accept the UTF-8 and UTF-16 encodings of Unicode </a><a href="http://www.w3.org/TR/xml/#Unicode">[Unicode]</a>; the mechanisms for signaling which of the two is in use, or for bringing other encodings into play, are discussed later, in <a href="http://www.w3.org/TR/xml/#charencoding">4.3.3 Character Encoding in Entities</a>.<br />
</blockquote><br />
As we see, XML standard requires only supports on UTF-8 and UTF-16, and XML parsers can freely make their decisions to support other encodings. Expat supports four encodings, that's all.<br />
<br />
So, if you want to use XML with Python, please think about it carefully when choosing your default encodings. If there are requirements to support "any" encodings, don't just use Python blindly.Anonymoushttp://www.blogger.com/profile/01776840235317220202noreply@blogger.com29tag:blogger.com,1999:blog-22431478.post-19204516620452124252009-09-04T10:15:00.000+08:002009-12-28T08:37:35.609+08:00GoTask:工作模型(二) 查询和任务管理<a href="http://cppof286.blogspot.com/2009/08/gotask_28.html">上一篇</a>里我说过,GoTask的三个要素是:提醒,分类和查询。但问题是:这三者是所有的时间管理软件都必须有的,那么GoTask和我们很熟悉的Outlook或者iCal有什么区别呢?<br />
<br />
GoTask设计的主要目的是为了支持长期任务管理,而在我看来Outlook和iCal更适合管理短期任务。所以要回答这个问题,我们不妨先看看短期任务和长期任务的差异。<br />
<br />
在我的经验中,多数情况下短期任务往往以小时为单位计算,这一点相信每一个Outlook用户都会很熟悉:当需要定义一个会议邀请时,Outlook总是以半小时为默认单位指定时间,而一个任务一般最长也就是全天,即所谓的All Day Event。但是Outlook并不擅长显示或处理持续时间超过一天的任务——或许重复任务(Recursive Tasks)算是一种,但其实际上是可以被分解的短期任务集合。在工作中我发现,我的同事们很少会在Outlook中大量定义跨天任务。<br />
<br />
显然,两种任务在时间安排上的差异首先会影响任务提醒功能。Outlook中的提醒虽然选择很多,但其主要目的都是通知用户某个任务将要开始。有人也许会注意到在任务开始之后Outlook实际上无法自定义提醒的频度,那是因为它假设任务开始之后总是能在短期内完成,除非用户忘记,否则没有必要多次提醒。但长期任务则不同,它常常需要对用户做多次提醒。这主要是为了便于划分任务阶段,同时也是为了能定期确定进度。如果在Outlook中要做这件事,那就得定义多个项目,然后每个项目定义单独的提醒时机。<br />
<br />
另一个问题是,我认为每个任务单独定义提醒频率的方案不适合长期任务。因为长期任务需要的提醒时机较多,如果每个任务都必须分别制定多个提醒时间,用起来比较麻烦;而且考虑到长期任务时间安排往往较灵活,我也没有必要将提醒定得过于死板。我的习惯是每周分两次检查任务列表,同时调整接下来几天的安排。所以长期任务的提醒方式最好是能统一定义的,比如要求提醒我所有“开始日期到今天大于十天,并且尚未完成的任务”。每次系统只需要查阅数据库里所有的项目,然后找到满足要求的就可以了。<br />
<br />
<br />
那么现在问题就变成了:我怎么才能定义这样的提醒?我的设想是通过查询来完成。换句话说,我希望提醒规则是定义于每个查询,而非每个任务中。例如,假定一个任务需要持续四个星期,而我需要第一和第三个星期提醒一次,那么我可以设定两个查询:<br />
<ol><li>查找每个已经开始,并且起始日期在一周前的任务。</li>
<li>查找每个已经开始,并且起始日期在三周前的任务。</li>
</ol>这样随着时间推移,我就能得到两次提醒。同样地,这个规则还可以被应用到所有其他的任务去。这种做法的好处是:如果我需要修正提醒的时机或频率,只需修改查询的定义,而后所有工作任务的提醒规则都能相应地更新。在长期任务数量巨大的情况下,这种组织方式比Outlook的方案更容易管理。<br />
<br />
这种设计在程序上还有一个好处:每个查询结果可以被再次利用。我可以用查询来构造一个简单的统计系统。比如我想知道过去两个星期里所有完成的任务占总任务的比例,我需要定义两个查询表达式,在得到查询的结果后做一个简单的百分比,就能得到我需要的数据。<br />
<br />
最后,在我的设想中这种设计也应当能够在一定程度上处理短期任务,但需要一个前提:GoTask的时间计量必须支持到小时或分钟。这样我就能通过定义一个检查“开始时间在当前15分钟之后”的查询来模拟Outlook的行为了。<br />
<br />
<br />
现在我们还剩下最后一个问题:分类。我将它留到下一篇中讨论。Anonymoushttp://www.blogger.com/profile/01776840235317220202noreply@blogger.com0tag:blogger.com,1999:blog-22431478.post-22540385371611720912009-08-29T13:02:00.000+08:002009-12-28T08:33:47.609+08:00GoTask: 工作模型(一):功能<a href="http://cppof286.blogspot.com/2009/08/gotask.html"> 上一篇</a>中我解释了GoTask应用的场合,那么现在我们自然而然地就有了第二个问题:我们该如何用GoTask管理任务呢?<br />
<br />
要回答这个问题,我需要研究一下我自己的工作。对我来说,我每天需要花在任务管理上的精力主要都用来完成两件事:<br />
<ol><li>分类:根据各种标准对任务进行区别。</li>
<li>排序:按事情完成的先后关系决定完成次序。</li>
</ol>有意思的是,我发现在工作中我很少需要对任务做排序。也许是因为我手头的任务往往繁琐而杂乱,任务之间彼此联系很少,又或者是老板已经规定了各个工作阶段。总之,事实上我很少有必须对手头任务排序的机会。另外,我发现自己同时追踪多个任务时效率很有限,远不如一个接一个地串行完成便于控制。所以多数情况下我只需要做个分类,剩下的事情就简单地按照时间先后定序即可。<br />
<br />
同时,我对分类的功能要求却很高。比如我常常需要同时和别的组的多个进行任务交接,这时我就需要把任务根据接洽对象的不同分为几类,然后对比每个交接工作的安排是否有所缺失。但与此同时,我也需要根据时间段对任务做划分,这样我才能知道大概在某一段时间里我需要做多少任务。有时候我同时接到很多任务,这时候我就得根据什么时候完成而它们分成几部分,而不能管他们从何处而来。<br />
<br />
谈到了时间我们就必须提到一个重要功能,也就是提醒。当我们需要管理的任务很多时,每个人都会或多或少忘记一些事情。这时候工具适时发出的提醒就显得非常重要。<br />
<br />
最后一个我需要的功能是查询。当任务数目太多的时候,单靠人去记忆显然有些勉为其难,既然我们已经对任务进行了分类,那么考虑使用某种形式的查询显然就是水到渠成的事情。<br />
<br />
如此我就得到了GoTask必须支持的三个功能:<br />
<ol><li>任务分类:可以根据使用者的标准不同自行定义。</li>
<li>任务提醒:在任务开始或终止时通知用户。</li>
<li>任务查询:每一个任务应该能通过某种方式查询其时间和分类。</li>
</ol>这其中分类本身包含两个用途:第一,它是显示的一部分,使我能得知当前任务的性质;第二,它是查询条件的一部分,使我能过滤掉一部分任务,从而关注最想关心的东西。<br />
<br />
这样,每当我得到一个新任务,我就可以在GoTask里增加一个项目,然后根据情况打一到多个标记作为分类。我可以每天早晨查询一次,确定今天必须完成的任务,然后每天下班时重新查询一次,看看有多少还没有完成。当然,如果到了设定的时间,GoTask应该提醒我任务将至,应该早做准备。<br />
<br />
<br />
看到这里或许大家会觉得我只是给自己重新画了个Outlook,因为Outlook也有任务,而且提醒、分类、查询一个也不少。别急,我正在考虑工作模型的下一个部分:复杂条件查询和长期任务跟踪。我们下次再说。Anonymoushttp://www.blogger.com/profile/01776840235317220202noreply@blogger.com0tag:blogger.com,1999:blog-22431478.post-69597899867348692782009-08-25T10:55:00.000+08:002009-12-28T08:34:21.351+08:00GoTask: 设想想写这个东西已经很久了。这一年多以来忙得昏天黑地,我这个念头只能一直埋在自己心里,从来没有真正付诸实践。一个月前有一次无意中和东哥聊起,突然发现这个念头就像一个心里的结,总是挥之不去。最重要的是,我越来越想试试能不能实现它。<br />
<br />
OK,那么我们回到正题。首先,什么是GoTask?<br />
<br />
GoTask是我想做的一个小软件,用来管理自己的个人工作事务。我希望它可以支持这样一些功能:<br />
<ol><li>以天为单位跟踪每天的工作项目列表。</li>
<li>支持以Tag为基础的历史搜索。</li>
<li>支持统计功能。</li>
<li>支持不同工作项目的合并和检索。</li>
</ol>在我的设想中,GoTask应该被设计为管理这样一些任务的:第一,它们需要一段较长的时间完成,比如几天甚至几个星期;第二,它们没有详细到每个小时的计划,只有大概的每日进度估计;第三,它们总是有明确的起始和结束时间。<br />
<br />
这么古怪的需求很大程度上和我的工作有关。因为工作中我总是处在这样一个环境里:每天任务随时随地出现,其中大部分都不很紧急但比较耗时,我可以选择在几天甚至几周内完成。另外最重要的是:这些事我肯定无法全部做完。所以我每天必须做的一件事就是取舍,有些确实可以不做的,就不管了;有的重要但不需要自己处理的,就交给别人;而有些则必须自己完成。同时,由于一部分任务几乎总是会被放弃,我希望我的工具能帮我做一些统计工作,比如它能分门别类地告诉我,在过去的三个星期内我的总任务有多少,做完的和放弃的比例有多少等等。<br />
<br />
有人也许想问:为什么不用Outlook的Calendar?因为我认为Outlook更适合管理当天开始并完成的短任务,以小时为单位。而我想要的是个能管理那些无明确计划的任务的工具。基于同样的理由,东哥强力推荐的iCal也给否了。另一个抛弃Outlook的理由是:它几乎没有统计功能。而这是我想做这么一个软件的主要理由。<br />
<br />
其实有一个软件在统计功能上非常接近我的要求,<a href="http://projecthamster.wordpress.com/">Hamster</a>,可惜后来研究了一番之后还是觉得它不是我想要的。主要的问题有两个:首先,它的界面更倾向于提醒那些当天必须做完的事情;其次,它的搜索功能弱了些。除此之外还有一个小瑕疵:它是个Gnome Applet,而我的系统里没有Gnome。<br />
<br />
所以我觉得也许我需要自己动手。今天先写到这里,具体的细节以后慢慢讨论。Anonymoushttp://www.blogger.com/profile/01776840235317220202noreply@blogger.com0tag:blogger.com,1999:blog-22431478.post-22296383124589753892009-08-25T09:11:00.000+08:002009-08-26T12:43:49.053+08:00关于重开Blog的说明终于开始认真地决定要用这个Blog了。<br />
<br />
说起来,这个Blog从注册开始也过了三年,可我从来没认真用过。原因相信是众所周知的,由于一些大家心照不宣的问题,在国内的网络环境里要想畅通无阻地访问Blogger实在是困难重重。虽然对我自己而言这从来都不是问题,好歹自己也是搞软件的,可既然开了一个Blog,总是希望大家都能读到。加上后来有一段时间基本上只用Hotmail和Live Messenger,自然比较倾向于集成做得更好的Live Spaces,这几年下来,几乎把这边给忘记了。<br />
<br />
但是这几年Live Spaces用得多了,却发现自己越来越不喜欢她。过于花哨而不实用的界面或许是一个因素,而真正的原因则有些难以启齿:太不自由了。为什么?因为我的Live Messenger上公司的同事太多,很多人都会跟着连到我的Blog上,这时要自由地对公司内外的技术发表评论难免有些束手束脚。也许这只是我个人的片面印象,但我在北京时,不少我敬重的同事对别家技术的了解程度似乎总是与我所预期相去甚远;反过来,他/她们对MS自家的技术却总有一种毫无来由的狂热。每当和别人争论的时候,他/她们都会言之凿凿地向每一个听众论证MS的每一项新技术是如何优秀;但恕我不恭,有时我发现这些技术他/她们自己甚至都没有体验过。这种感觉在我来到Redmond一年之后更加明显:我所认识的许多Redmond的同事们私下里从不避讳任何对公司产品缺陷的评论。<br />
<br />
熟悉我的朋友们都知道,由于出身的原因,我总是更倾向于关注MS之外,特别是Open Source世界的一些动向,而且最要命的是我喜欢顺嘴说几句自己公司的坏话。为此我的一位大学好友兼MS Fan甚至直接把《冰与火之歌》中“忧郁的艾迪”这一名头送给了我,评曰:勤勤恳恳的乌鸦嘴。无论这种习惯是好是坏,在Live Spaces这种众目睽睽的环境下我发现自己无法毫无顾忌地写出对很多事情的真实看法,更不可能持续我对Open Source的关注。<br />
<br />
<br />
回到主题。既然我已经决定重新启用这个Blog,那么总要做一些变化。无论如何,我希望在这个Blog里更多地讨论一些我自己喜欢的话题,偏重技术。这其中包括MS的东西,更包括很多Open Source的内容。这里是我个人的Blog,我也不是MS的新闻发布官。虽然维护公司形象也是分内的事,但也犯不着处处往公司脸上贴金,只是希望说一些真实的个人看法。<br />
<br />
<br />
至于语言呢,基本上还是英文和中文,中文为主。毕竟是母语,表述起来也比较得心应手。不过有时候我也会用英文换换口味,特别是很多技术术语无法找到合适的中文表达的时候。<br />
<br />
最后,关于国内访问的问题,我确实是无能为力了。只是作为一个著名的乌鸦嘴,我心里多少还存了点心思。如果可以的话,我希望能坚持到能从国内顺畅无阻地访问Blogger的那一天。Anonymoushttp://www.blogger.com/profile/01776840235317220202noreply@blogger.com0tag:blogger.com,1999:blog-22431478.post-1159199462064096152006-09-25T23:48:00.000+08:002006-09-25T23:51:02.076+08:00Congratulations! Finally the Blogger can be accessed by Chinese people! Thanks to the effort of everybody that works on it!Anonymoushttp://www.blogger.com/profile/01776840235317220202noreply@blogger.com0tag:blogger.com,1999:blog-22431478.post-1142173784970941522006-03-12T22:17:00.000+08:002006-03-12T23:10:44.163+08:00<div style="text-align: center;">The first article here<br /><br /></div>Two days ago my friend Bobby told me that he had make a plan two years before. His plan is to write an article per year, until the <span style="font-style: italic;">www.blogger.com</span> is not blocked by the GFW.<br /><br />That sounds fun. Inspired by his idea, I started a similar project, except that I will post an article per month. And I had made a decision that all my articles should be written in English. Don't get me wrong, I love my homeland and language. I do it just because I wanna improve my English.:)<br /><br />Oh by the way, I also have a shadow version blog in MSN spaces. That is in mainly Chinese. But I am afraid the space is toooooo slow. :(Anonymoushttp://www.blogger.com/profile/01776840235317220202noreply@blogger.com0