显示标签为“python”的博文。显示所有博文
显示标签为“python”的博文。显示所有博文

2010年5月22日星期六

二分查找算法

JavaEye 在几天前发表了一篇关于二分查找算法的文章: 你是那10%可以实现二分查找算法的程序员吗?,讲得好像让所有的程序员都很尴尬的样子。最后文章还给出了一位 JavaScript 高手对二分查找算法的实现。但是这个算法其实也是有 bug 的。。。我们可以查看 Python 里的 bisect 模块,对于二分查找算法,分为 bisect_right 和 bisect_left 两种情况,这是由于所查找的元素在预排序算法中可能有多个存在或者元素可能会是一种复杂的数据结构,所以当然就必须考虑是查找左边的位置还是右边的位置,或者插入左边的位置还是右边的位置了。对于简单的元素不需要考虑插入左边的位置还是右边的位置,不过 Python 文档中举的例子中的元素是个复杂的数据结构,所以需要考虑这种需求。

附上那位写了《JavaScript高级程序设计》的作者使用 JavaScript 实现的代码:

//Copyright 2009 Nicholas C. Zakas. All rights reserved.
//MIT-Licensed, see source file
function binarySearch(items, value){

var startIndex = 0,
stopIndex = items.length - 1,
middle = Math.floor((stopIndex + startIndex)/2);

while(items[middle] != value && startIndex < stopIndex){

//adjust search area(调整查找范围)
if (value < items[middle]){
stopIndex = middle - 1;
} else if (value > items[middle]){
startIndex = middle + 1;
}

//recalculate middle(重新计算中项索引)
middle = Math.floor((stopIndex + startIndex)/2);
}

//make sure it's the right value(确保返回正确的值)
return (items[middle] != value) ? -1 : middle;
}

可以在 Firebug 或者其他浏览器的 JavaScript 调试器中测试这段代码, 也可以把这段代码翻译成 Python 代码,再添加一个小小的测试:

# coding=utf8
def binarySearch(items, value):

startIndex = 0
stopIndex = len(items)
middle = (stopIndex + startIndex) // 2

while items[middle] != value and startIndex < stopIndex:

#adjust search area(调整查找范围)
if value < items[middle]:
stopIndex = middle - 1
elif value > items[middle]:
startIndex = middle + 1

#recalculate middle(重新计算中项索引)
middle = (stopIndex + startIndex) // 2

#make sure it's the right value(确保返回正确的值)
return (items[middle] != value) and None or middle

if __name__ == '__main__':
items = [1, 2, 3, 4, 4, 4, 4, 4, 5, 6]
print binarySearch(items, 4)

检测运行一下,当然就发现问题了。

最后附上 Python 标准库中的实现代码:

## from file: /path/to/python-install-prefix/lib/pythonx.x/bisect.py
def bisect_right(a, x, lo=0, hi=None):
"""Return the index where to insert item x in list a, assuming a is sorted.

The return value i is such that all e in a[:i] have e <= x, and all e in
a[i:] have e > x. So if x already appears in the list, a.insert(x) will
insert just after the rightmost x already there.

Optional args lo (default 0) and hi (default len(a)) bound the
slice of a to be searched.
"""

if lo < 0:
raise ValueError('lo must be non-negative')
if hi is None:
hi = len(a)
while lo < hi:
mid = (lo+hi)//2
if x < a[mid]: hi = mid
else: lo = mid+1
return lo

bisect = bisect_right # backward compatibility

def bisect_left(a, x, lo=0, hi=None):
"""Return the index where to insert item x in list a, assuming a is sorted.

The return value i is such that all e in a[:i] have e < x, and all e in
a[i:] have e >= x. So if x already appears in the list, a.insert(x) will
insert just before the leftmost x already there.

Optional args lo (default 0) and hi (default len(a)) bound the
slice of a to be searched.
"""

if lo < 0:
raise ValueError('lo must be non-negative')
if hi is None:
hi = len(a)
while lo < hi:
mid = (lo+hi)//2
if a[mid] < x: lo = mid+1
else: hi = mid
return lo

嗯,学习算法知识的话,到 Python 的标准库中查看源代码也是一种非常好的学习方式啊!

--
http://magicoding.appspot.com/entry/0
2010,04,26

2009年10月15日星期四

自定义一个 zope3 的 Python 2.5 开发环境

自定义一个 zope3 的 Python 2.5 开发环境

----------------------------
LinFeiYu 2009,10,10

1. 创建一个自定义环境的目录::

$ sudo mkdir /opt/py25
$ sudo chown your_login_name:your_login_name /opt/py25

2. 首先需要自己编译一个 zlib 库

参照 limodou 前辈的文章 ( 编译Python 2.5.4带zlib http://www.zeuux.com/blog/content/1553/ ) ::

$ tar xzvf zlib-1.2.3.tar.gz
$ cd zlib-1.2.3
$ ./configure --prefix=/opt/py25 --shared
$ make
$ make install
$ make clean

3. 然后开始编译 Python 2.5.4

这里的 configure 是从 http://aur.archlinux.org/packages/python25 的 PKGBUILD 抄来的,呵呵 ::

$ tar xzvf Python-2.5.4.tgz
$ cd Python-2.5.4
$ ./configure --prefix=/opt/py25 --enable-shared --with-threads --enable-unicode
$ make
$ make install
$ make clean

4. 设置 Python 2.5 库

如果你的操作系统中已经存在一个二进制的 Python 2.5 的话,你可能不需要这一步了。

检查是否存在 /usr/lib/libpython2.5.so ,如果没有的话 ::

$ sudo ln -s /opt/py25/lib/libpython2.5.so.1.0 /usr/lib/libpython2.5.so

注意:这个方法可能不大好,如果你有好的方法,请告诉我。

5. 安装 setuptools

::

$ tar xzvf setuptools-0.6c9.tar.gz
$ cd setuptools-0.6c9
$ /opt/py25/bin/python setup.py install
$ /opt/py25/bin/python setup.py clean

7. 安装 zc.buildout

同上。

8. 一些可能用到的 Python 包的安装

基本思路同上。比如 PIL, ReportLab, xapian-bindings 等。

脚本语言之于开发及部署相关

脚本语言之于开发及部署相关

----------------------------
LinFeiYu 2009,10,05

脚本语言的简便和高效致使它们得到广泛的应用。在 Linux 发行版系统中使用脚本语言开发管理工具、应用程序现在已经非常流行。比如很多发行版的包管理程序都是用 Python 开发的。相信大家在 Linux 上使用 Python, Ruby 等脚本语言进行开发或者产品部署的时候,特别是 Python ,经常有一些比较烦心的版本冲突问题。一个比较好的解决方法我想就是自己重新编译一个需要的版本,比如在 /opt/py25 编译一个 Python 2.5 的版本,然后使用这个版本来进行开发和部署。这样做其实是有很多好处的。

1. 首先是这个版本是从源码编译的,虽然不能说比发行版提供的二进制包或者定制的包性能上好,但是我认为它可以更加的简洁和稳定,而且你可以自定义一些选项,做一些有用的优化!

2. 其次是与操作系统本身的版本分离,完全不受干扰。虽然像 zc.buildout, virtualenv 等优秀的虚拟环境构造程序可以非常好的完成这个工作,但是他们还是在跟系统紧密相连的那些版本关联,偶尔还是会发生一些意想不到的故障。

3. 升级和卸载方便。由于和操作系统中的版本完全分离,所以啥时候升级,升级成什么样子都随你折腾。卸载的话就更加方便了,几乎把目录一删除就可以了。操作系统中的版本升级也很少会影响我们自己编译的版本。最多是自己重新编译一次。

2009年8月31日星期一

Python Web Framework

Python Web Framework

---------------------------
LinFeiYu 2009,08,30

感觉 Python web 框架都在向 zope 方向进展。这是最近发现的一个地方。为什么呢?

zope 中有一个叫做注册表的东西,这个注册表分为本地注册表和全局注册表(globalSiteManager),所有的组件不是在本地注册表中就是在全局注册表中,可以通过 Python 代码方式将组件注册到注册表,也可以通过 zcml 文件直接注册组件。虽然有人跟我说过 zcml 中注册的组件是注册到全局注册表中,然而在我学习了 wsgi 中间件之间的调用之后,我发现那个说法应该是错误的。 zcml 中的组件注册应该只是注册到本地注册表,而不是注册到全局注册表!如果开发一个大型的应用的话,每个模块都有其组件注册到注册表上,这样 zope 的注册表将是非常的大的。在 zope组件架构 ( http://www.muthukadan.net/docs/zca.html#adapters ) 中提到:“局部组件是持久化组件,而全局组件是保存在内存之中。全局组件是根据应用的设置进行注册的,而局部组件是在应用启动的时候从数据库中加载到内存的。” 我想这个跟 Windows 的注册表有些神似,不过却不是真正的好方案,Windows 的注册表已经被批得一塌糊涂,比如《Unix编程艺术》中所指出的那样。使用 zcml 配置文件据说也是很多 Python 开发者拒绝 zope 的一个原因。

Django 的发展中也许遇到了类似的问题,它们必须把组件组装到一个地方,让整个框架可以方便地统一管理这些组件。于是,我们看到了 Django 的 admin 模块中也出现了一个类似注册表的东西,这篇文章中: 修正 Django Step by Step 的一些例子 ( http://www.vpsee.com/2009/07/update-examples-in-django-step-by-step/ ) 指出了这个问题。毫无疑问,注册表功能将会在 Django 中越来越多的出现,最后可能走向 zope 的注册表解决方案。

国内 Python 领袖人物之一的 limodou 在其尚未开发完成的 Uliweb 框架中更是使用了一种非常类似 zcml 的解决方案,不同的是作者使用的是 ini 配置文件。具体介绍看这里:第一章 Uliweb介绍 ( http://sites.google.com/site/learninguliweb/home/chapter1 ) 中的 “资源共享的处理方式” 一段。在资源的配置上它应该还没有做到 zope 中那样可以根据 weight 来调整合并资源文件的深度。更不用说 zope 的 viewlet 那样灵活的设计了。

总之,在这些或者非常火爆,或者尚在发展的轮子中,我们还是看到已经存在的设计,或许他们重新造轮子只是想把原来的设计简化而已。。。

今天,无意中看到同事 Youngking 很久以前的一篇文章:又一个框架-bobo ( http://blog.xmu.me/2009/06/14/framework-bob/ ),发表时间是 2009,06,14 ,而文章最后一句话,“这个框架目前还没有正式发布,Jim Fulton声称会在下周一发布。”估计这个东西已经出来很久了,那么有时间一定要去弄来玩玩,或许它带来了很多新的东西。呵呵 :-)

Python

Python

----------------------
LinFeiYu 2009,08,29

Python 目前是我的工作程序语言。这个程序语言以简洁、优雅著称。
使用 Python 是让人愉快的。好像技术界的很多大牛都给了 Python 很高的评价。
然而,最近我却有些不大开心。
首先是版本的兼容问题。虽然 Python 2.x 大部分时候是向后兼容的,但是还是有一些地方让人比较难受。特别是新的版本中新增或者改进的功能在旧版本中几乎完全不能使用。而 Python 3.x 更是一下子去掉了向后兼容,大家几乎都要从头开始!当很多应用还停留在 Python 2.x ,甚至是 Python 2.4 的时候,Python 3.1 在 Python 3.0 刚发布不久之后就马上发布了。这个速度也太快了!
另外一个是性能问题。最近看《Unix编程艺术》,其中提到,不仅相对与编译语言,而且相对于其他脚本语言,Python 也是效率低下、速度缓慢的。
现在的 *nix 系统管理程序越来越多的看到 Python 的身影。这似乎是一件很鼓舞人心的事情。然而几个事情还是让我有些担忧。有一次我把 Ubuntu Server 从 6.06 升级到 8.04 ,中间出现了一个小问题,这个小问题直接导致了这个系统完全无法使用。这个问题是这样的:Debian/Ubuntu 最强劲的包管理系统 apt 是基于 Python 语言的,升级过程中,与 apt 相关的某个 python 脚本可能由于文件系统的逻辑错误导致无法使用,结果升级安装在这里失败了,整个安装升级到此为止。而此时我比较傻,重启了系统,结果进入不了系统,提示整个系统处于 Read Only 状态什么乱七八糟的。使用 single 模式进入最基本的系统还是提示缺失某些重要的命令,而这命令就跟 apt 有关。修复了 apt 软件包之后把整个系统重新升级,重启之后就完全恢复正常了。然而却浪费了我几个小时的时间。当然这似乎不能怪罪于 Python 了。然而这么重要的系统功能依赖于 Python 这样的脚本语言,我总觉得不大合适。
相信很多人都很不乐意于使用 Java 开发的应用程序,然而现在 Linux 下的很多应用程序使用的是 Python 语言。我已经看到过很多的问题,都是 Python 脚本引起的。比如 Fedora 的安装程序 Anaxxx 在分区阶段偶尔会出现一些问题,这些问题从出错的提示看都是 Python 脚本。Magic Linux 使用的 smart 程序是基于 Python 开发的,使用中也出现一些奇怪的问题。我的 Arch Linux 使用 wicd 程序管理网络,按照 Arch Linux 官方建议的设置,现在和 dbus 的通讯还是存在权限的问题,这个 wicd 也是用 Python 开发的。 PyQt 、 PyGTK 、 wxPython 等被广泛应用与 Linux 发行版的桌面程序开发,然而他们的运行缓慢,效率低下!也许 Python 真的非常适合于快速开发,然而性能问题不能不面对啊!

Python 现在是很多 Linux 发行版的一个必须的系统级脚本语言,就像 Perl 一样。这也不见得是一件好事情。Fedora 11 默认的 Python 安装了 Paste 、 setuptools 、 simplejson 等 Python 包,然而某些 Python 包,比如 Paste 和 setuptools 似乎被削去了很多东西,导致开发中出现问题,结果只能把这些包卸载了,重新从各自的源码安装。而由于 Python 版本升级的兼容问题,发行版面临另外一个问题,就是一旦 Python 版本需要升级,其他很多系统相关的包都需要重新调整编译等。一个很典型的例子是 Magic Linux ,他们在 2.0/2.1 版本中均使用 Python 2.4 版本。然而,当想将 Python 2.4 升级到 Python 2.5 的时候,他们发现好多好多的依赖,这个依赖太多了,所以他们打算等待下一个发布版本 2.5 再升级到 Python 2.5 。然而当他们开始发布 2.5 的 alpha 版本的时候他们已经将 Python 2.4 升级到 Python 2.6 了,而 Python 2.5 不见踪影。

相信我们都对“依赖”感到不爽,从 Windows 的 dll hell 到 Linux 发行版中各种软件包的依赖问题,简直不能忍受!然而,这个问题,的确很难解决啊!

想想 C/C++ 非常的稳定,根本不在乎新技术如何迅猛的发展,多年过后你还是可以用回你原来的技术创建非常高效的应用程序!

不久前,google 宣布了一项计划,将为 Python 提速。这是一件非常让人欣喜的事情。然而几个月过去了,我们没有看到 google 这项计划的半点进展。等待是痛苦的。。。

2009年4月8日星期三

出来了个www.buildout.org

没想到最近出来了这个: http://www.buildout.org
大有将 python 中的 web 应用使用 zc.buildout 统一管理组件版本。
觉得这东西的使用似乎越来越微妙了。
pycon 2009 似乎提到相关的问题,即 distutils 某些功能要去除,转移到类似 virtualenv/zc.buildout 这样的非核心包中。
既然大家都这么热捧 zc.buildout ,似乎不应该对其有意见。
一个比较好的 pycon 2009 介绍:
Brett Cannon: PyCon 2009 recap: Best PyCon ever!

2009年3月4日星期三

zope2 现在可以通过easy_install安装了

http://regebro.wordpress.com/2009/02/27/zope-2-now-in-egg-form/

Zope 2.12 alpha 1 has been released. It’s completely “eggified”, meaning that all parts of it are separate python modules, installable with setuptools easy_install command. The main egg is called just Zope2, and you can therefore now install Zope 2 with “easy_install Zope2″ from the command line. Of course, this will install it in the system library, which is probably not what you want. So you probably want to use virtualenv to create a separate installation, or use buildout.

Here are the commands I used to test this alpha version:

virtualenv zope212 # Create a python sandbox for testing

cd zope212

bin/easy_install Zope2 # Install Zope 2

# make coffee while Zope 2 gets downloaded and installed

bin/mkzopeinstance

cd testinstance # Or whatever you called it

bin/zopectl fg

Yeah, that’s it! Works like a charm. Even on Python 2.6! Zope 2.12 will be released probably around a similar time as Plone 4. Plone 3.2 is already completely eggyfied, but Plone buildouts still need to have special recipies for installing Zope 2. With Zope 2.12 this will no longer be necessary, and you can install Plone just by doing an easy_install Plone, and get all of the parts installed. Which is totally cool!

So thanks to everyone involved in this, and also to everyone involved in eggifying Zope3, without which this never could have happend!

Posted in python, zope Tagged: eggs, plone

==============================
这是一个好消息!
赶快试下。。。
希望能工作在 python2.5 和 python2.6 上。哈哈
不要像不久前发布的 zope 3.4.0 那样,一上来就只认 python 2.4
PyPi 上的说明:
http://pypi.python.org/pypi/Zope2/