星期四, 八月 30, 2007

OpenSource 奖项

Open Source Award,似乎是个不错的主意,不过在Google上搜索却找不到一个比较权威的奖项,看看这个
http://sourceforge.net/community/index.php/landing-pages/cca07/

也许这个SourceForge的奖还不错,值得参考 , 这其中居然有Wenquanyi(不错的中文字库)。

星期三, 八月 29, 2007

Robocode

很早以前在看一本Java的书的时候就知道Robocode这个项目, 非常有创意: 用Java实现一个 控制坦克的算法, 不同的算法坦克对战。你可以在网上下载到各种坦克,和自己坦克对战来提升自己坦克的战斗力,你还可以参加网上的坦克联赛,非常有趣!还可以看到排名,在1对1的排名表中,一位来自中国的坦克排在第16位。

在我的Ubuntu上,要先安装 sun-java5-jre(我试过sun-java6,不行,运行出错),然后切换java版本到sun-java:
sudo update-alternatives --config java
再使用官网上下载的setup文件来安装
java -jar  ./robocode-setup-1.4.2.jar
然后就ok了,在安装目录下运行robocode.sh,进入坦克世界吧!

其官网上的一句话非常精辟的概括了robocode:"Build the best - destroy the rest!"

星期二, 八月 28, 2007

awk的强大

为了分析从sourceforge下载的数据,再次体会awk的强大。

我想看每个项目从去年到今年的排名的变化,所以先将去年和今年的rank数据merge一下:
./sfmerge.py sfRawRanksData2006-Dec-01.txt sfRawRanksData2007-Jun.txt  | grep -E '[a-zA-Z0-9\-]+ +[0-9]+ +[0-9]+' | sort -k 2 -n  > sfrank0607.txt
这个合并后的文件虽然有了两个排名,但没有排名的变化,因此只能动用awk了:
cat sfrank0607.txt| awk '{printf("%20s %10d %10d %10d\n",$1,$2,$3,$2-$3);}' | more

这下一览无余了。

星期一, 八月 27, 2007

Python 名字作用域

因为经常为遗忘,这里记录一下:
* 基本规则-LGB(Local-Global-Builtin),这个很容易理解
x=9
def px1():
  print x  #会输出9

def px2():
  x=8
  print x  #会输出8, 并且全局的x不会改变

* "编译"时判断域 - 这个比较容易理解错
x=9
def px():
  print x  #x未定义(因为执行时x还未赋值)
  x=8  #编译时决定了x为局部

* from X import Y/*
会将模块x的名字引入当前模块(类似于y=x.y),尽量避免这种用法,大部分情况下应该用import X

星期日, 八月 26, 2007

Python的类

Class是Python相当有特色的成分,Python的类是C++的大量简化,但又有所创新
按c++的术语来看,Python类的所有成员都是public, 所有函数都为virtual。
* Python class中的赋值(method外)定义了类属性(类似于C++的staitc 成员变量)
* Python method中定义的self变量,相当于C++的public类成员变量,可以外部直接访问。(但method如没有运行,则此name未创建,不能访问)
* method的名字如果为__X__,则表示hook(比如构造或运算符重载)
* instance.method(args) 等价于 class.method(instance, args)
* 继承合乎理解,object.name会按 instance->class->super的顺序解析,super的解析是从左到右,深度优先。
* 类中的name,如果是__xxx,则自动在之前被加上类名,不被继承。

星期六, 八月 25, 2007

C++/Java/Python/Ruby

这是一篇刚看的文章
http://www.dmh2000.com/cjpr/

基本上同意作者的观点,但是有两点重要不同,一是作者忘记了C,我认为C才是最佳的系统编程语言,而不是C++,另外一点,我不喜欢Ruby。

(c++的一个幽默: what is a protected abstract virtual base pure virtual private destructor?  )

星期五, 八月 24, 2007

valgrind II

今天又花了点时间研究valgrind,发现昨天有句话写的不是准确,valgrind不仅通过虚拟方式,它也使用了插装来帮助代码检查,当然插装是在汇编指令上做的,而且valgrind的插装是可以通过写插件的方式来扩展,这样就成就了一个valgrind支持多个tool。插件是通过c写的,看了一下代码,有点复杂,还需要了解valgrind虚拟机的指令集。不过这还是让我对valgrind更加高看,体系架构独一无二,作为2004 Open Source Award得主看来是有两把刷子的。

一个额外的发现:valgrind 缺省情况下在检测到错误时,只是报错,而没有启动gdb,这在有些时候不太方便定位,可以使用命令行参数,让valgrind在检测到错误时,提示是否启动gdb,象这个样子即可:
 valgrind --db-attach=yes prog

这里有英文的信息 http://www.amule.org/wiki/index.php/Using_gdb_and_valgrind

星期四, 八月 23, 2007

valgrind vs ...

我之前就对valgrind(linux下的一款自动查错工具)印象颇佳,今天又验证了一把:
#include <stdlib.h>
int main()
{
        char * a = (char *)malloc(100);
        a [101] = 0;
        free(a);
}
这个程序,在windows下用boundschecker检查,要在free的时候,才检测到内存越界,而且如果把a[101]改成更大的值,比如a[105](跳过guard字节),boundschecker居然检测不出来,这有点对不起这款工具的名称了。

而在Linux下,valgrind可以准确检测出越界,并且就是在越界发生的地方报告错误,方便定位。但valgrind也有很大的遗憾,它不能检测出数组的越界,而这正是boundschecker的强项。造成这种差异的原因在于,两种工具的检测原理不同,boundschecker使用代码插装,而valgrind使用虚拟机。

所以各种开发工具差别还是很大的,完成同样一件事,因为方法不同,得到的结果也不同,有时配合起来反而效果不错。

星期二, 八月 21, 2007

从源文件中提取版本号

在build软件的过程中,经常需要版本号(比如打标签,压缩包的时候),从代码中获取是最好的方法,shell命令就可以做到,比如代码中有这样的语句:
version = "1.0.2"

可以用这样的命令截取下来:
grep "version\s*=" sourcefile | cut -d \"  -f 2

如果是在makefile中,就可以赋值给变量了:
VERSION := $(shell grep "version\s*=" sourcefile | cut -d \"  -f 2)

星期一, 八月 20, 2007

sourceforge统计-PHP,Ruby

Java和C/C++就不必统计了,一如既往的强势。
统计一下PHP吧(后面是排名)
 
2007/06月份:
phpmyadmin 5
orangehrm 21
phpgedview 25
freenas 35
fckeditor 43
xoops 43
gallery 47
p4a 55
drakecms 89
webcalendar 95

而在2006/12:
phpmyadmin 3
gallery 9
phpgedview 9
fckeditor 12
xoops 18
covide 69
coppermine 72
webcalendar 79

基本上没有明显的变化趋势(从排名上看,今年似乎有一些下滑)。
Ruby也统计了一下,基本上都在1000名以后,离主流还比较远。

星期日, 八月 19, 2007

Sourceforge统计-python

我很喜欢看sourceforge上各个项目使用的编程语言的统计情况,曾经会隔一段时间就去统计一次,但这样在sourceforge上看很累,尤其现在sourceforge访问的速度又很慢,幸好FLOSSmole提供了sourceforge原始数据的下载,这样在本地来看就方便多了,更大的好处是可以比较当前数据和历史数据。

首先要实现一个小程序sfmerge.py来将FLOSSmole下载的多份原始数据merge:
import os
import sys

g_sf = {}

def rd_single(f):
    fp = file(f)
    lines = fp.readlines()
    for line in lines:
        if line[0]=="#": continue
        line_a = line.strip ("\n").split("\t")
        if g_sf.has_key(line_a[0]):
            g_sf[line_a[0]] += line_a[1:]
        else:
            g_sf[line_a[0]] = line_a[1:] + []

   
def wt_merge():
    for sf, sfinfo in g_sf.iteritems():
        print sf,
        for info in sfinfo:
            print info,
        print
   
if __name__ == '__main__':
    try:
        for f in sys.argv :
            rd_single(f)
    except:
        sys.exit(1)
               
    wt_merge()

然后就可以使用这个程序,再结合其它文本工具来查看我想看的信息了:
./sfmerge.py sfRawRanksData2007-Jun.txt sfRawProgLangData2007-Jun.txt | grep Python | sort -k 2 -n | more

上面这条命令可以统计使用Python的项目,并按排名排序,我比较关心以Python为主编程语言的项目,大概可以在前200名的项目中看到zenoss(26), pydev(44), fretsonfire(125), bitpim(140), taskcoach(178),这几个项目。而在半年前(06年12月)的数据中,只有pydev位居前200。

星期六, 八月 18, 2007

Python陷进-shallow copy

看看下面的执行过程就可以看出来了,
>>> a=[[]]*3
>>> a
[[], [], []]
>>> a[0].append(3)
>>> a
[[3], [3], [3]]
>>>

这就是Python的shallow copy的副作用,这比直接用list赋值的shallow copy还要迷惑一些。

星期二, 八月 14, 2007

c/c++头文件的双重保护

在large scale c++ software design 一书中提到, 在头文件中有必要使用"双重"防重复包含的宏,象这样:
#ifndef INCLUDE_XXX_H
#define INCLUDE_XXX_H

#ifndef INCLUDE_YYY_H
#include yyy.h
# endif
因为如果不这样做,冗余的包含会使得编译效率下降,并且作者还给出了使用CFRONT的实测结果,不过是基于CFRONT编译器的,但是在现代的大型项目中很少看到这样的双重ifndef语句,原因在于现代的编译器大多可以处理这种情况,会在内部优化掉,使得即使没有"双重"包含宏,也不会下降编译效率。

这里有很好的说明。

星期日, 八月 12, 2007

c/c++代码检查

静态检查很有用,尤其是项目比较大的时候,我曾经花了很长时间寻找合适的静态检查工具(pclint很好,但不具备扩展性),最终我比较看好 Coverity,Codesonar, Parasoft C++ Test,并且从网站上看,前两者技术上要更好一些,它们支持基于程序执行分支的规则,而Parasoft C++ Test则"知名度"较高,它不能支持基于分支的规则。

还有一类工具,也是用静态技术,但主要不是为了检查,而是为了度量,比如统计代码中各种函数调用图,include图等,这类工具我用的很少。

由于c++的复杂性,这类工具(无论是检查还是度量)做的好的不多,而Java的检查和度量工具就要多一些。

星期六, 八月 11, 2007

好书-《large scale c++ software design》

最近在看的一本书,实际上已经好久没有认真看C++相关的书了,只是这本书实在是独树一帜,英文版是96年出版的,在网上看有些人评价这本书过时了,可在我看来这是一本非常好非常好的书。

这本书讲解了C++软件开发过程中被很多人忽视(或者说很多人不了解)的"物理设计"技术,这个"物理设计"我感觉翻译的有点别扭,不过也想不到好的替代。大意说来就是如何在遵循逻辑设计(就是其它书所说的设计)的前提下,合理高效的组织文件,目录,组件,包等承载逻辑设计的"物理实体"。书的大半部分都是在讲这个主题,让人耳目一新。遗憾的是中文的翻译水准那是一贯的x,有些地方只能边看边猜了。

看这本书让我想起大学时代曾经看过的一本清华大学出版的《磁盘加密与解密》,当时也有类似的感觉,好书啊,现在居然在google上都搜不到一条相关信息了。