星期一, 十二月 31, 2007

反 spambots

spambots是指那些在网页上自动提交垃圾/广告信息的机器程序,我曾经深受其害,在我以前的blog中(那时用b2搭建),大量的垃圾留言几乎使我不得不关闭了留言功能。

现在的网页上的Form信息提交很多都依赖于"人工检测",比如最常见的就是给出一个机器无法识别的图像识别,可是由于机器人的智能越来越高,有很多网页给出的这种图像识别也是越来越难,甚至连真人也很难识别了,不信你试试blogger的留言就知道了。下面一篇blog提出的方法则完全不同,它不会对"真人"造成任何的困扰:

http://nedbatchelder.com/text/stopbots.html

它所使用的技术虽然有些复杂,但很实用,能够完全避免"图像识别"带来的困扰,有机会我会试试。

星期日, 十二月 30, 2007

python map/filter/reduce

python有几个内置的函数很有意思:map/filter/reduce,都是对一个集合进行处理,filter很容易理解用于过滤,map用于映射,reduce用于归并,这几个词还是太抽象了,下面的代码精确的说明了这几个函数的用途:

def map_imp(function, sequence) :
    if function is None: return list(sequence)
    retvals = []
    for element in sequence:
        retvals.append(function(element))
    return retvals

def reduce_imp(function, sequence) :
    arg1 = function(sequence[0])
    for arg2 in sequence[1:] :
        arg1 = function(arg1, arg2)
    return arg1

def filter_imp(function, sequence) :
    retvals = []
    for element in sequence:
        if (function is None and element) or function(element) :
            retvals.append(element)
    return retvals

对于这种逻辑性强的东西,用语言来描述是无助的,代码则要清晰的多。 

星期六, 十二月 29, 2007

python classmethod和staticmethod

在早期的python版本(2.2之后)中就有了这两个东东,staticmethod就对应于C++的静态成员函数,而classmetho在C++中是找不到对等体的(它的第一个参数是类对象,而不是类实例)。

def smethodimp(arg):
  do somthing
smethod = staticmethod(smethodimp)

def cmethodimp(cls, arg):
  do something
cmethog = classmethod(cmethodimp)

一般情况下,smethod和smethodimp可以用同一个名字(比如都叫smethod),同样cmethod和cemthodimp也可以同名。

这样的定义总是怪怪的,在2.4版本之后,我们可以用decorator来重写这难看的代码,不过decorator的功能远超出这么简单,我暂时还不能理解其精髓啊(等用时再看吧)。

星期四, 十二月 27, 2007

python __file__ 与相对路径

用__file__ 来获得脚本所在的路径是比较方便的,但这可能得到的是一个相对路径,比如在脚本test.py中写入:

#!/usr/bin/env python
print __file__

按相对路径./test.py来执行,则打印得到的是相对路径,
按绝对路径执行则得到的是绝对路径。
而按用户目录来执行(~/practice/test.py),则得到的也是绝对路径(~被展开)

所以为了得到绝对路径,我们需要 os.path.realpath(__file__)。

星期三, 十二月 26, 2007

django调试

用python/django有个好处,调试时用 print 可以在控制台直接输出,而不会送到web输出,也就是说本地的控制台输出和送给brwoser的输出是分开的,这比php要方便一些。

还有一个方法得益于django内置的error page,只要在想要的地方放一个assert False,就可以在django的错误页面中看详细的http信息,变量信息等。

如果这些还不过瘾的话,也许 django loggin 也值得一试(我还没试过)。有了这些调试手段,一般的动态调试基本是用不上了。。。


星期二, 十二月 25, 2007

Leah Culver

这是一个达人mm,通过出售笔记本外壳的"广告"位,为自己攒钱买到了配置相当了得的Macbook pro,广告是通过激光雕刻上去的,因为她在一家机械加工相关的网站工作,这件事也使得她攒了相当的名气(不信可以用google试试) 。

让我很感兴趣的是,她是一个了得的Python/Django程序员, 并作为Lead developer创建了 Pownce 网站,这个网站还是很酷的,基本上可以算一个社交网站,但提供了基于Adobe Air的客户端(这个不是Leah开发的,呵呵),似乎基于Adobe Air的应用也逐渐多了起来。。。

星期日, 十二月 23, 2007

sqlite 与 mysql的时间函数

很不幸,sqlite和mysql在SQL函数的支持上有很多差异,比如:

这是官方mysql的时间函数说明:
http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html

这是官方sqlite的时间函数说明:
http://www.sqlite.org/cvstrac/wiki/wiki?p=DateAndTimeFunctions

mysql里面如果 select year(field) 在sqlite里面就需要写成 select strftime("%Y", field), 这个麻烦的说。

星期四, 十二月 20, 2007

VIM与python

python的缩进识别给很多编辑器带来了困难,但VIM还是灵活的,通常我用下面的设置(在~/.vimrc中写入):

autocmd FileType python set tabstop=4|set shiftwidth=4|set expandtab|set softtabstop=4

这是用于控制python文件类型的一些设置,这样在编辑其它文件时不会受这个影响,注解如下:
set expandtab 只是在输入tab时转tab到空格,如果是已经有的tab,可以用:retab命令来强制转换到4个空格。
set softtabstop=4是为了让vim可以在backspace时将4个空格当成一个tab删除用的,这样省却每次按4次。

 

星期一, 十二月 17, 2007

makefile for asciidoc

不愿意每次键入长长的命令来执行asciidoc的编译,那么下面这个makefile正是为此准备的,自动检查是否需要编译,如果需要则自动调用asciidoc:

HTMLS := $(patsubst %.txt,%.html,$(wildcard *.txt))

all: $(HTMLS)

%.html: %.txt
        asciidoc -a toc -a numbered $<

星期日, 十二月 16, 2007

mysql事务

由于phpmyadmin的存在,我通常"抵制"使用mysql的命令行,不过老实说,有时用mysql的命令行也是满方便的,昨天为了验证事务的特性,还动用了mysql的命令行。

show create table xxx;
create table xxx ( a int primary key , b ) engine=innodb;
start transaction;
insert into xxx values (1,1);
insert into xxx values (1,2);
commit;

结果是 第一条记录 被插入进去了,说明了事务并不管sql语句的返回,事务只保证这些语句统一的执行或不执行。

星期六, 十二月 15, 2007

asciidoc格式

用了这个asciidoc,感觉还不错,稍微记录一下常用的asciidoc格式:

文件头: 文件标题后加一行字数和文件头相同的等号
章节: 这个类似于Mediawiki,用 == 标题 == (后一半等号可省略)
URL: url[]
图像: image::url[],如果是段落内的图像,则两个冒号改为一个
段落: 可以使用样式打头,比如  NOTES: 内容
表格: 可以用  `-----`-----(内容用空格对齐),也可以用 ````~宽度(内容用逗号分隔)
列表: 用 - 或者 * 打头,要加一个空格

总得来说和wiki比较相似,但基于文件来操作,可以更灵活一些,比如可以使用喜欢的编辑器,可以diff/merge等。

星期二, 十二月 11, 2007

WordPress Clone in 27 Seconds

这个niubility了,http://fallingbullets.com/blog/2006/aug/06/wordpress-clone-27-seconds-part-1-40/ 号称27妙搞定一个blog(还是wordpress克隆版的)

我试了一下,27秒确实太夸张了,估计只够Ctrl-C/Ctrl-V的时间,而且这个帖子里还有一些遗漏没有写清楚:
× 记得要设置 setting.py 中的数据库,sqlite3是比较简单的
× 还要设置setting.py中的template路径,否则会找不到模板
× 还要在admin中创建一个blog时时间要提前一天 ,或者在url.py中调用django.views.generic.date_based.archive_index时增加一个参数(allow_future=True),或者正确的设置setting.py中的时区(我就是Asia/Shanghai),否则都不能显示当前的blog。

这个代码里用到了model的Slug类型,这是一种短字符串,通常由字母,数字,短线(减号)构成,显然很适合做URL,django的slug支持一个populate_from参数,可以在admin后台界面里从另一个字段自动产生这个slug字段(这个很酷的)。

星期一, 十二月 10, 2007

gcc的虚函数表

gcc的虚函数表是怎么组织的?它是和版本相关的,在2.x的gcc版本中(我知道的是2.7和2.9)我们可以看到虚表中每个函数指针占用了8个字节,这8个字节的后四个字节才是虚函数指针,而在3.x的版本中(比如3.3),则类似于VC,4个字节一个函数指针,这比较紧凑。

一般情况下,这不会影响什么,但如果要写一些特殊的代码,依赖于虚表的格式(比如通过虚表去调用函数),那么问题就来了,把格式弄错的话,就可能会导致严重的" Pure Virtual Function Called"问题,直接导致程序Crash掉。

不过不要混淆这个问题和 这篇 文章 提到的问题,虽然结果都是一样的"Pure Virtual Function Called"。。。

星期日, 十二月 09, 2007

mysql事务

事务在mysql中,是否支持取决于后端的表驱动,如果是缺省的MyISAM表是不支持事务的,通常需要InnoDB来支持事务,创建表时可以指定这个表的驱动类型,比如:

create table vv ( v varchar(4)) engine=innodb;

对于支持事务的InnoDB表,缺省时,如果不显式启动事务,每条命令会自动启动一个事务,并被自动commit。但我们可以更改一个系统变量autocommit,当autocommit设置为0时(set autocommit=0;),可以让mysql象oracle一样,命令不会触发事务的commit,需要手动的commit或者rollback(可以在多条命令后commit或rollback)。但在commit之前,我们可以用select将改动查询回来(也就是说查到的是buffer里面的数据),但其它的session是不会查到这些没有提交的数据的。

当然,即便设置了autocommit=1; 一样可以通过 start transaction来启动事务。



星期六, 十二月 08, 2007

asciidoc

已经有很多简单标记语言了,不是吗? (wiki,markdown等),这个asciidoc也是一种,它有什么新式武器吗? 没有,它也是将带标记的text文件转换为html或其它格式,看起来很像docbook,不过git选择了asciidoc,而git是Linus大佬的项目,所以asciidoc还是有它的过人之处的。

简单的在Ubuntu下sudo apt-get install asciidoc就可以安装了,下载一个例子 http://www.methods.co.nz/asciidoc/faq.txt ,然后执行:
asciidoc faq.txt
就可以得到一份漂亮的内嵌css的html文档faq.html了,不错吧,试试看编辑一下txt文件,加入中文,都没有问题。

asciidoc的过人之处在于:
+ 格式简单,比docbook简单, 这种简单的格式带来的结果是asciidoc文件本身已经可以具备很好的文档可视性(一个docbook源文件看起来还是有些费劲的,被xml tag穿插的有些支离破碎),这可能对写文档的人连贯自己的思路有很大的好处。
+ 表达能力强,在格式简单的基础上,asciidoc的表达能力并不象某些wiki那么弱,比如asciidoc可以支持三种格式输入(doctype):article,book和manpage(他们三种的基本语法是类似的),显然支持book就意味着asciidoc有较好的表达能力。
+ 工具易用, asciidoc本身的工具只有一个命令文件(asciidoc),就支持三种格式(backend)输出:xhtml11/docbook/html4,一般情况下用xhtml11就很好用了,如果需要更复杂的输出,可以先转换到docbook,再用docbook toolchain做进一步转换。在命令行下使用 asciidoc -b backend -d doctype file 就可以了,通常 -b/-d都不用指定,缺省值分别为xhtml11和article,所以命令行使用就非常简单,比docbook的一整套toolchain用起来平易近人一些。

写了这么多优点,并不是说asciidoc没有缺点,通常一个新事物总是容易先看到优点,而在使用中再逐步看到缺点,我用的不多,所以不敢妄下结论,不过有一个缺点先提一下,它的官网上的User Guide文档写的不好,比较晦涩 :))

星期五, 十二月 07, 2007

sqlite3 命令行

sqlite3提供了命令行接口一般直接运行sqlite3 database 就可以进入命令行了
一般的SQL命令直接以分号结尾都可以执行,其它的命令都以句号(.)打头(好奇怪),比如几条关键的常用命令:
.tables   列出当前数据库的表
.schema 列出当前数据库的表格式
.quit 退出(这个一定要记住,呵呵)

当然,最最重要的是,.help 可以获取帮助。


星期四, 十二月 06, 2007

安装一个django app

以安装django snippets为例:
1. 预先需要的package要先安装(有些可以通过apt-get很方便的安装)。
2. 从服务器上svn checkout下来到本地django project的cab子目录下。
3. 在setting.py中增加一个app,如 mysite.cab。
4. 运行 manage.py syncdb 来同步数据库。
5. 修改urls.py 增加一行 (r'^snippets/',include('mysite.cab.urls'))。
6. templates总用到了一些模板的基础文件,需要自己创建比如base.html,可以就放在 cab/templates下。

现在就可以运行manage.py runserver了。。。

星期六, 十二月 01, 2007

mysql的char和varchar

mysql提供了char和varcha两种存储短字符串的类型,我是在看了文档之后才知道这里面花花肠子很多的,把要点记录在案(好记性不如烂笔头啊):

char用于定长字符串,在建表时指定长度,在存储时自然也是定长,但我们可以向char里面存储不超过长度限制的字符串,不够长时会自动补空格(在后面补,前面不补),查询时mysql会将后面的所有空格去掉,char的长度限制为255以下。

varchar用于变长字符串,也在建表时指定长度,在存储时是变长(使用长度+字符串),因此可以节省存储空间,varchar的特性在不同mysql版本间差异较大, 5.0.0.3之前的版本也会在查询时截去后面的空格,但>=5.0.0.3版本之后不会了(同时在存储时也保留了后面的空格),5.0.0.3版本之前有255的最长限制,但5.0.0.3之后取消了这个限制,长度只受限于记录长度(65535),如果一条记录有多个varchar,大家就需要分享这个65535了。

由于mysql支持多种字符集,所以长度的定义就有些岐义,我试了一下,长度是按字节来的,也就是说一个中文字符可能会占据多个字节。

两种字符串类型的选择也挺有意思,显然char类型的性能应该好一些,但varchar可以降低数据库大小,而这对大型数据库的性能很关键,所以一般来说,都应该使用VARCHAR,除非:
1)你的字段确实是定长的(比如MAC地址),当然应该使用char。
2)你的数据库很小,你不在乎空间的浪费,而希望改进性能,可以考虑用char。

官方的参考文档:
http://dev.mysql.com/doc/refman/5.0/en/char.html