2006年12月03日

在2006/12/02,在中科院举行了CPUG的第十三次会课,主要是由我给一些爱好者进行Python的一个讲座。没什么准备,因为内容很熟。会议依然是由Zoom.Quiet主持,到场大约二、三十人吧,我没有统计。不过说实在的,听说过Python的的确不多。不过也有一些对Python相对熟悉,还有一些可能对Python感兴趣。

总之是一次不错的交流,至少知道研究生院在什么地方了。 :P

2006年11月13日

这几天加入了协作编程的插件,pairprog。它的主要功能是

1. 任何一个UliPad实例都可以成为一个server
2. 其它的UliPad实例可以与某个server进行连接
3. 一个server加若干个client构成一个组
4. server端和客户端的基本操作:光标移动、增加、删除都可以广播到其它组内成员
5. 组内成员可以通过聊天进行交流
6. server端可以添加新的共享文件,可以踢除某人
7. client可以重取某个文件

它的作用是可以多人同时查看相同的文件,并进行修改。可以用在一个局网,我想也可以用在internet上,不过我没有试验。这样虽然我们见不着面,但是可以使用这一功能进行代码方面的交流。

它的原理是p2p,因此目前不支持代理服务器,要么在局网使用,要么可以不通过代理接入internet.

使用方法:

进入插件管理->选中pairprog插件
重启UliPad
[工具]->[Concurrent Program]

English Translation:

I’v added concurrent programming plugin these days, pairprog. And the
main features are:

1. Each UliPad instance can be server
2. Others UliPad instances can connect to the server
3. A server and several clients will compose a group
4. The basic operation of server side and client side, such as: caret
moving, text adding, text deleting, can be broadcast to other members
of the group
5. There is a chatroom which group member can user it to exchange each other
6. The user who create the server is the manager, and he can add new
shared document, and kick off somebody
7. Non manager user can re-get some document

So users can use this plugin to review the same documents at the same
time. You can use it in a local network or maybe on internet(but I
don’t test it now). Even through we don’t meet each other, but we can
use it to talk about the source code.

It didn’t support proxy now.

How to use it?

[Tool]->[Plugin manager]->Check pairprog plugin
restart UliPad
[Tool]->[Concurrent Programming]

If you want to try this new feature, you should update from svn or
download snapshot version. Some functionalities will be still in
optimized.

Try it. Hope you enjoy it.

此功能在最新的svn中或snapshot下载。有兴趣的可以试一试。功能可能还在优化中。

2006年09月19日

新时刻到来了,许多新特性的增加,新模块的加入使得 Python 更为人所注目。这一新版本增加的功能的确很多,以至于Anthony Baxter在邮件列表中宣布新版本发布时都说:

It’s been nearly 20 months since the last major release
of Python (2.4), and 5 months since the first alpha
release of this cycle, so I’m absolutely thrilled to be
able to say:

On behalf of the Python development team
and the Python community, I’m happy to
announce the FINAL release of Python 2.5.

This is a *production* release of Python 2.5. Yes, that’s
right, it’s finally here.

在新版本发布时还有些战战兢兢(thrilled)的感觉。真是经过了很多的努力啊。

关于新特性早就说过了。有兴趣的赶快下载吧!

2006年09月13日

在 xmlrpc 中使用代理服务器,以前在我写的 blog 备份的小程序中的确也有,不过现在 donews 的 metaweblogapi用不了了,总是报错,以致于我已经无法使用那个小程序来备份了。今天看到一个 blog 是讲关于如何让 PyPiBrowser 来支持代理服务器的,感觉不错,但改造了一下介绍给大家。

PyPi 是 Python 的Package Index 的简写,它相当于 Perl 的CPAN是一个集中的模块,应用程序发布的地方。它提供了 xmlrpc 的服务,你可以用于查看模块信息。关于 PyPi 的 xmlrpc 的说明见这里。上面还有一些 python 代码你可以直接进行试验,不过上面的代码可没有代理服务器的设置。

PyPiBrowser 是一款使用 PyQt 开发的GUI程序,可以用来浏览 PyPi 上的信息。在没有看到上面那个 blog 之前我还以为它是通过抓网页来实现的,因为我当时不知道 PyPi 还提供了 xmlrpc 的功能。

下面的小程序是我写的一个测试程序,你可以用它来显示 UliPad 的metadata信息。

import xmlrpclib
import urllib2

class UrllibTransport(xmlrpclib.Transport):
    def __init__(self, proxy, verbose=0):
        self.proxy = proxy
        self.verbose = verbose
       
    def request(self, host, handler, request_body, verbose):
        self.verbose = verbose
        url=’http://’+host+handler
        if self.verbose:
            print "ProxyTransport URL: [%s]" % url

        request = urllib2.Request(url)
        request.add_data(request_body)
        # Note: ‘Host’ and ‘Content-Length’ are added automatically
        request.add_header("User-Agent", self.user_agent)
        request.add_header("Content-Type", "text/xml") # Important
       
        proxy_handler=urllib2.ProxyHandler({’http’:self.proxy})
        opener=urllib2.build_opener(proxy_handler)
        f=opener.open(request)
        return self.parse_response(f)
   
proxy = ‘yourproxy’
url = ‘http://cheeseshop.python.org/pypi’

import xmlrpclib

if proxy:
    server = xmlrpclib.ServerProxy(url, transport=UrllibTransport(proxy))
else:
    server = xmlrpclib.ServerProxy(url)

version = server.package_releases(‘UliPad’)[0]
meta = server.release_data(‘UliPad’, version)
for k, v in meta.items():
    print k, ‘:’, v

UrllibTransport是一个我写的类,它可以在创建对象时传入一个 proxy 参数,如:http://proxy.com:8000,而那篇文章上的却是通过设置环境变量,在代理类中无法传入,所以不方便。我改造后,这样代理服务器你在哪里设置都可以:可以直接传入,也可以设在环境变量中,只要:

proxy = os.environ['http_proxy']

就可以得到,然后再传入即可。

然后在创建xmlrpclib.Server()时根据是否有代理而选择是否设置transport参数即可。

上面最后几行是找到 UliPad 的版本信息,它是一个列表,然后再次调用返回第一个版本的metadata数据并打印出来。

注意,为了发布程序,所以有花括号都转为了全角。因此如果你直接拷贝代码请转换回来。因为donews不认。

2006年09月05日

tinyurl.com 是一个很有趣的网站,它的功能就是把你输入的 url 进行压缩,可以缩短你的 url,这样方便你拷贝。当然真正的 url 可能保存到它的网站去了。的确一个很长的链接可以变得很短,以后可以考虑用它来处理邮件列表的链接,只是不清楚能够保留多长时间,至少短时间是可以用的。比如我的blog链接可以这样访问:

http://tinyurl.com/otyra

2004年05月11日

sets是 Python 2.3 中新增的,它可以用来处理集合类型的数据。什么是集合?无序、唯一。


在这个模块中提供了两个集合类:Set(可变集合)和ImmurableSet(不可变集合)。


在我以前写过的一篇Blog中(一个Python小程序:目录比较程序(一) )有一段代码需要求两个目录中相同文件名的列表,我当时是将两个列表进行排序,然后通过一遍扫描进行求解,还是有一点算法的难度的。如果使用集合类就简单和清晰多了。代码如下:


import filecmp, sys, os
from os.path import walk, isfile, join, basename, normpath, splitext
import sets



if __name__ == “__main__”:
    dir1=normpath(sys.argv[1])
    dir2=normpath(sys.argv[2])
    len1=len(dir1)+1
    len2=len(dir2)+1
    files1=[]
    files2=[]
    exts=['.pyc', '.bak', '.ddd', '.png', '.gif', '.jpg']


    def visit(arg, dirname, names, files=files1, length=len1):
        if basename(dirname)!=’CVS’:
            files +=[join(dirname, file)[length:].replace(‘\\’, ‘/’)
                for file in names if isfile(join(dirname, file))
                and splitext(file)[1].lower() not in exts]


    walk(dir1, visit, 0)
1    dirs1 = sets.Set(files1)


    def visit(arg, dirname, names, files=files2, length=len2):
        if basename(dirname)!=’CVS’:
            files +=[join(dirname, file)[length:].replace(‘\\’, ‘/’)
                for file in names if isfile(join(dirname, file))
                and splitext(file)[1].lower() not in exts]


    walk(dir2, visit, 0)
2    dirs2 = sets.Set(files2)
   
3    common=dirs1 & dirs2
4    dirs1.difference_update(common)
5    dirs2.difference_update(common)
6    files1 = list(dirs1)
7    files1.sort()
8    files2 = list(dirs2)
9    files2.sort()
10    commons=list(common)
11    commons.sort()
   
12    match, mismatch, error=filecmp.cmpfiles(dir1, dir2, commons)


    print ‘%s vs %s’ % (dir1, dir2)
    print ’state filename’
    print ‘—– ——————————’
    for f in files1:
        print ‘  >   %s’ % f
    for f in files2:
        print ‘  <   %s’ % f
    for f in match:
        print ‘  =   %s’ % f
    for f in mismatch:
        print ‘ !=   %s’ % f


第1行:生成dirs1集合
第2行:生成dirs2集合
第3行:求dirs1和dirs2的交集,即求两个目录中相同文件名的集合
第4行:求只在dirs1中存在的文件名,带有_update的方法会更新原集合对象,而不带的则会生成新的集合
第5行:同第4行,求只在dirs2中存在的文件名
第6-7行:将集合转化为列表,并排序
第8-9行:同第6-7行
第10-11行:同第6-7行
第12行:比较两个目录中同名的文件


不过集合是无序的,因此当你需要按顺序输出元素时则需要先将其转化为有序的列表或元组,再进行输出。这一点有些麻烦。


生成一个列表可以从list或tuple甚至dictionary直接生成。如果直接使用dictionary,则会取出键值作为集合的元素,如:



>>> a={1:’a', 2:’b'}
>>> b=sets.Set(a)
>>> b
Set([1, 2])


如果想将字典的值生成集合怎么办呢?



>>> b=sets.Set(a.values())
>>> b
Set(['a', 'b'])


更详细的关于集合类的使用请查阅 Python 2.3 的文档。

作为实验性的 NewEdit 项目现在已经转移到 www.tigris.org 上去了,访问地址为:http://newedit.tigris.org 。上面已经有了可以运行的框架代码,欢迎大家下载交流。请记住,这是一个实验性项目,目前只具备一些基本的功能,随着它的发展,功能会越来越强,最终应可以应用于你的日常工作之中。


现在代码只可以通过 cvs 下载,不过从tigris.org上下载源代码比起sf.net上要容易得多了。下面是匿名用户下载代码的说明(详情可以参考项目主页上的cvs使用说明)。


检测源代码使用 CVS 客户端。例如:



cvs -d :pserver:anoncvs@cvs.tigris.org:/cvs login


需要输入口令时,直接敲入回车即可。


随后是



cvs -d :pserver:anoncvs@cvs.tigris.org:/cvs checkout newedit


 

2004年05月10日






file( filename[, mode[, bufsize]])


file()函数是2.2中新增的函数,它与open()函数一样,相当于open()的别名,不过比open()更直观一些。


读出一个文件的内容很简单:



text = file(filename).read()


这里我省略了模式(mode)参数,它缺省为’r'。


现在 Python 已经支持三种主要平台的回车符:’\n’是Unix的换行符、’r'是Macintosh的换行符、’\r\n’是Windows的换行符。那么在打开文件时使用’U'或’rU’模式就可以同时支持这三种换行符。


如果要对文件进行一行行的处理,有多种方法:



  • 先一次性将文本行读到一个列表中,再对列表进行处理


lines = file(filename).readlines()
for line in lines:
    print line



  • 使用文件对象的readline()方法进行一行行的处理


f = file(filename)
while True:
    line = f.readline()
    if line:
        print line
    else:
        break



  • 还有就是2.3中的新方法,在for循环中直接使用文件对象


for line in file(filename):
    print line


这是因为文件对象中增加了迭代功能。


注意:上面读出的每一行都带有回车符,因此在某些情况下你可能需要将它们去掉。

enumerate是python 2.3中新增的内置函数,它的英文说明为:









enumerate( iterable)

Return an enumerate object. iterable must be a sequence, an iterator, or some other object which supports iteration. The next() method of the iterator returned by enumerate() returns a tuple containing a count (from zero) and the corresponding value obtained from iterating over iterable. enumerate() is useful for obtaining an indexed series: (0, seq[0]), (1, seq[1]), (2, seq[2]), …. New in version 2.3.

它特别适合用于一个for循环时,当我们同时需要计数和元素时可以使用这个函数。举个简单的例子,有一个字符串数组,需要一行一行打印出来,同时每行前面加上计数,从1开始。



s = ['abc', 'This is a test', 'Hello, Python']
for i, line in enumerate(s):
    print i+1, line

2004年05月09日

今天把NewEdit放在了tigris.org上了,原来是在开源共创联盟上,但不知怎么地cvs用不了了,但我的帐户没有问题。也实在懒得去和cosoft去联系。还有一点就是,我对使用ssh有些讨厌,虽然我现在用它是一点问题都没有(使用cygwin),但每次都要输入口令,好麻烦。想到SubVersion是放在tigris.org上,于是就上去看了看,并申请到了一个帐号,不过现在项目还未经过审批。但就是未审批,我已经可以使用cvs上传我的源码了,真不错。而且它的cvs很简单,与我平时工作中用的一样。只要在cvs login时输入一次口令就可以了,以后就不用再很麻烦的输入口令了。大家有兴趣可以在上面创建自已的项目。


访问我的NewEdit项目可以去newedit.tigris.org。