很多中国人的习惯是按照农历过生日的,但是在Google Calendar里添加农历生日只能一年一年的添加,而不能一次添加多年,这样就很不方便。为了避免这个麻烦,在几个月前写了一个程序,用来生成按年重复的农历生日的ICS文件,导入Google Calendar里,避免一年一年的添加带来的麻烦。程序是一个Web应用,运行在GAE(Google App Endine)之上,地址在这里: http://spur.appspot.com
前几天有网友给我发信说他在用这个工具,问我能不能开源,因为appspot随时可能会被封掉,这样就用不了了。如果开源的话别人拿到源代码至少可以自己部署起来使用。我想这也是个不错的主意,本来这只是我个人写着玩的东西,能对人有帮助还是很高兴的。
于是在Google Code上建了个项目,把源代码放了上去,地址: http://code.google.com/p/lunar-cal-ics-gen/ 。
简单说明一下:
- 程序使用python语言编写,运行于GAE平台, 要想在本机运行,需要下载GAE SDK。当然,也可以修改代码改造成不依于GAE的Web应用。
- Web框架使用了从friendfeed开源出来的tornado,具体介绍可见这里 。
- 生成日历使用的是icalendar 库,计算农历的代码取自pyzh 项目。
目前添加日历的方式是以ics文件做为中介,最初曾设想通过GData API直接将日历添加到Google Calendar,不过由于时间关系,一直没来得及做这件事,也不确定这个想法是否可行。
程序截图
起了个名叫做segcala, 地址 http://segcala.googlecode.com。
这几天对Scala比较感兴趣,看了一些资料,不过语言这东西光看不练还是没感觉,就写了这样一个分词程序。使用了Chih-Hao Tsai的mmseg分词算法。做为依赖注入的粉丝,程序里使用了google guice做为依赖注入容器。
Scala在JVM上的运行效率可以达到和Java差不多的程度。做为同时支持面向对象和函数式编程思想的语言,其强大的表达能力则是Java所忘尘莫及。
以mmseg算法中求一个chunk的自由语素度的代码为例,看看Scala如何使程序变得更加简捷和清晰:
Scala版:
def largestSumMorphemicFreedomDegreeRule(chunks: List[Chunk]): List[Chunk] = {
val c = chunks.reduceLeft((c1, c2) => {if (c1.degreeOfMorphemicFreedom > c2.degreeOfMorphemicFreedom) c1 else c2})
chunks.filter(chunk => (chunk.degreeOfMorphemicFreedom == c.degreeOfMorphemicFreedom))
}
再看看Java版(取自solo L的mmseg库):
public class LSDMFOCWRule implements IRule {/* (non-Javadoc)
* @see org.solol.mmseg.core.IRule#invoke()
*/
public final IChunk[] invoke(final IChunk[] chunks) {
LSDMFOCWRuleComparator[] orderedChunks = new LSDMFOCWRuleComparator[chunks.length];
for (int i = 0; i < chunks.length; i++) {
orderedChunks[i] = new LSDMFOCWRuleComparator(chunks[i]);
}
Arrays.sort(orderedChunks);
int index = 0;
double degreeOfMorphemicFreedom = orderedChunks[index].getChunk().getDegreeOfMorphemicFreedom();
List list = new ArrayList(1);
list.add(orderedChunks[index].getChunk());
index++;
while (index < orderedChunks.length) {
if (orderedChunks[index].getChunk().getDegreeOfMorphemicFreedom() == degreeOfMorphemicFreedom) {
list.add(orderedChunks[index].getChunk());
} else {
break;
}
index++;
}
IChunk[] degreeOfMorphemicFreedomChunks = new IChunk[list.size()];
list.toArray(degreeOfMorphemicFreedomChunks);
return degreeOfMorphemicFreedomChunks;
}
static class LSDMFOCWRuleComparator implements Comparable {
private IChunk chunk;
public LSDMFOCWRuleComparator(IChunk chunk) {
this.chunk = chunk;
}
public IChunk getChunk() {
return chunk;
}
public int compareTo(Object obj) {
IChunk another = ((LSDMFOCWRuleComparator) obj).getChunk();
double temp = another.getDegreeOfMorphemicFreedom()
- chunk.getDegreeOfMorphemicFreedom();
if (temp > 0D) {
return 1;
} else if (temp < 0D) {
return -1;
} else {
return 0;
}
}
}

上面这幅图来自这篇文章:Mosh Pit as Innovation Model。
长期以来,知识是一种财富,掌握在少数人手中,很多“专家”乐此不疲的囤积知识,生怕别人偷走他们的想法。Web 2.0改变了这一切,我们可以看到,知识传播不在是少数知识所有者的专利,而是形成了一个知识网,每个人都可以成为知识分享者。
Karl Nelson提出了“开源知识(Open Source Knowledge)”的概念:“信息过时的速度是非常快的,特别是在技术领域,如果你将其存在你的头脑中不会产生什么价值,保存其价值的最好的办法是与他人共享你的知识 ”。
但是想真正使教育适应这一变化很难,这需要观念上的改变,教育本身就有一定的惰性,短时间内很难改变。但是对于那些出生于数字时代的小孩来说,他们都是数字原住民,他们习惯了网络,习惯了从网络上获取和分享。只是我们的老土教育还在束缚着他们。