<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>落 &#187; Development</title>
	<atom:link href="http://liluo.org/class/development/feed/" rel="self" type="application/rss+xml" />
	<link>http://liluo.org</link>
	<description>落就是一道风景线……</description>
	<lastBuildDate>Tue, 09 Aug 2011 11:22:28 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>使用PIL给图片添加水印</title>
		<link>http://liluo.org/2011/08/%e4%bd%bf%e7%94%a8pil%e7%bb%99%e5%9b%be%e7%89%87%e6%b7%bb%e5%8a%a0%e6%b0%b4%e5%8d%b0/</link>
		<comments>http://liluo.org/2011/08/%e4%bd%bf%e7%94%a8pil%e7%bb%99%e5%9b%be%e7%89%87%e6%b7%bb%e5%8a%a0%e6%b0%b4%e5%8d%b0/#comments</comments>
		<pubDate>Tue, 09 Aug 2011 11:19:31 +0000</pubDate>
		<dc:creator>落落</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[PIL]]></category>

		<guid isPermaLink="false">http://liluo.org/?p=700</guid>
		<description><![CDATA[前几天在做一个给指定相册添加水印的功能，使用的是PIL(Python Image Library)。
先去看一下网上，找到这篇：Watermark with PIL (Python recipe) 于是，处理水印的核心代码就差不多有了～

当然，问题也接着来了，首先就是拿到的图片文件和水印文件。我这边得到上传图片文件基本上会是文件二进制数据流或者由Flash post过来的application/octet-stream类型的二进制数据流，并不能像参考中的代码使用指定路径拿到文件，所以数据流进行处理：
import Image, ImageEnhance
from cStringIO import StringIO
img = Image.open(StringIO(img_data)) # img_data 是post过来的数据流
这样就可以拿到一个Image对象了。再使用类似参考代码对它进行水印处理。
然后在上传图片的时候，依然使用原来的机制，这里再把加过水印的数据流丢出去：
new_img = StringIO()
img.save(new_img, img_format, quality=100) # quality来指定生成图片的质量，范围是0～100
reutrn new_img.getvalue()
代码上线不久之后，就有同事反映说有png图片上传之后会原图会变掉，我拿png去上传之后效果正常，于是把他那张图拿过来测试，果然报错。后来发现他那张png使用的模式是'RGBA', 而我们一般情况下的png或者gif模式是'P'，会不会是因为图片模式问题呢？
测试：
img = Image.open('/Users/luo/p.png')
img.show()
在这个时候图片就已经被奇怪的变化了 ＃＃
后来多次尝试发现在 img.save() 时指定format='PNG'时效果正常，于是另加上了mode判断：
if img.mode != 'RGBA':
img_format = 'JPEG'
else:
img_format = 'PNG'
然后在保存时
img.save(new_img, img_format, quality=100)
本地环境测试ok，然后代码提交～
完整代码：
from cStringIO import StringIO
import Image, ImageEnhance
LEFT_TOP     = 'lt'
LEFT_BOTTOM  = 'lb'
RIGHT_TOP    = 'rt'
RIGHT_BOTTOM = 'rb'
WIDTH_GRID = [...]]]></description>
		<wfw:commentRss>http://liluo.org/2011/08/%e4%bd%bf%e7%94%a8pil%e7%bb%99%e5%9b%be%e7%89%87%e6%b7%bb%e5%8a%a0%e6%b0%b4%e5%8d%b0/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Debian 6 安装小记</title>
		<link>http://liluo.org/2011/07/%e5%b0%8f%e8%ae%b0-debian-6-%e5%ae%89%e8%a3%85/</link>
		<comments>http://liluo.org/2011/07/%e5%b0%8f%e8%ae%b0-debian-6-%e5%ae%89%e8%a3%85/#comments</comments>
		<pubDate>Sun, 31 Jul 2011 09:51:28 +0000</pubDate>
		<dc:creator>落落</dc:creator>
				<category><![CDATA[LAMP]]></category>
		<category><![CDATA[Debian]]></category>

		<guid isPermaLink="false">http://liluo.org/?p=692</guid>
		<description><![CDATA[上个月入手了mac，就把thinkpadr400冷落了蛮久。想着太浪费了，于是想着开始折腾系统。最开始是考虑unix中的freebsd, openbsd, netbsd，后来觉得还是回归linux吧，ubuntu太大众而且特别是那个紫色调太不喜欢，opensuse有用过，centos也在服务器上用过，思来想去了最后决定尝试下Debian。



下载时选择的是stable版本的debian-6.0.2.1-i386-CD-1.iso，然后刻盘安装。哈哈，我另外还有一台老旧的安装xp系统的thinkpadr60，用它安装刻录软件，加配3个月前买的外置刻录机，各种cd, dvd盘，装备齐全的连自个儿都感动了～
安装
其实Debian6的安装还是很方便的，甚至有点类似装win。另外还可以参考Debian GNU/Linux 安装手册 
开始使用
安装完成重启打开时，第一感觉就是简洁，经过opensuse的华丽，看到Debian真是别有一番味道。第二感觉还是简洁，它没有像Ubuntu硬塞进来很多用得到用不到的各种软件各种工具。整体看起来让人很舒服。
添加源
Debian中源列表文件在 /etc/apt/sources.list，因为默认是没有sudo的，所以暂时需要先su root, 没有vim暂时先用vi。
首先要把带有类似"deb cdrom"字眼的行给注释掉，不然系统会先找cd，因为没注意到这里让我纠结了很久。然后就是添加源，国内的话用网易的源还是不错的选择，将以下文字添加到/etc/apt/sources.list

deb http://mirrors.163.com/debian squeeze main non-free contrib
deb http://mirrors.163.com/debian squeeze-proposed-updates main contrib non-free
deb http://mirrors.163.com/debian-security squeeze/updates main contrib non-free
deb-src http://mirrors.163.com/debian squeeze main non-free contrib
deb-src http://mirrors.163.com/debian squeeze-proposed-updates main contrib non-free
deb-src http://mirrors.163.com/debian-security squeeze/updates main contrib non-free

完成之后，更新源并安装sudo：

apt-get update
apt-get install sudo
#要使用sudo,需要给相应的用户加上sudo权限
#添加写入权限
chmod u+w /etc/sudoers
vi /etc/sudoers
#在root ALL=(ALL) ALL下面添加
luo ALL=(ALL) ALL # luo是我的用户名
#保存退出，然后去除可写入权限
chmod u-w /etc/sudoers
#然后退出root
exit

安装中文支持

sudo [...]]]></description>
		<wfw:commentRss>http://liluo.org/2011/07/%e5%b0%8f%e8%ae%b0-debian-6-%e5%ae%89%e8%a3%85/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linux中安装MongoDB及简单入门</title>
		<link>http://liluo.org/2011/03/linux%e4%b8%ad%e5%ae%89%e8%a3%85mongodb%e5%8f%8a%e7%ae%80%e5%8d%95%e5%85%a5%e9%97%a8/</link>
		<comments>http://liluo.org/2011/03/linux%e4%b8%ad%e5%ae%89%e8%a3%85mongodb%e5%8f%8a%e7%ae%80%e5%8d%95%e5%85%a5%e9%97%a8/#comments</comments>
		<pubDate>Tue, 29 Mar 2011 06:57:21 +0000</pubDate>
		<dc:creator>落落</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MongoDB]]></category>

		<guid isPermaLink="false">http://liluo.org/?p=659</guid>
		<description><![CDATA[MongoDB是一个使用由C++编写的基于分布式文件存储的数据库开源项目，旨在为WEB应用提供可护展的高性能数据存储解决方案。下面说下安装方法以及简单入门知识。
1、下载
到官网 http://mongodb.org 去下载最新的稳定版本，目前是 mongodb-linux-i686-1.8.0.tgz
2、解压


mv mongodb-linux-i686-1.8.0.tgz /usr/local/
cd /usr/local
tar xvf mongodb-linux-i686-1.8.0.tgz
mv mongodb-linux-i686-1.8.0 mondodb
rm -y mongodb-linux-i686-1.8.0.tgz



3、运行
需要创建一个存放数据的目录(默认是/data/db/)，创建目录并启动：


mkdir -p /data/db/
/usr/local/mongodb/bin/mongod


如果想使用自己指定的目录来存储数据，加上--dbpath选项：

/usr/local/mongodb/bin/mongod --dbpath /path/to/data/dir

4、使用JavaScript Shell工具简单入门
默认链接的是test数据库

/usr/local/mongodb/bin/mongo
MongoDB shell version: 1.8.0
connecting to: test
&#62;

MongoDB简单入门
内容引用鱼哥博客



插入数据到集合


下面我们来建立一个test的集合并写入一些数据. 建立两个对象, j 和 t , 并保存到集合中去.
在例子里 ‘&#62;’ 来表示是 shell 输入提示符


&#62; j = { name : "mongo" };
{"name" : "mongo"}
&#62; t = { x : 3 };
{ "x" : 3  }
&#62; db.things.save(j);
&#62; db.things.save(t);
&#62; [...]]]></description>
		<wfw:commentRss>http://liluo.org/2011/03/linux%e4%b8%ad%e5%ae%89%e8%a3%85mongodb%e5%8f%8a%e7%ae%80%e5%8d%95%e5%85%a5%e9%97%a8/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Memcached 安装、使用（Python操作）以及常用方法</title>
		<link>http://liluo.org/2011/03/memcached-install-python-use/</link>
		<comments>http://liluo.org/2011/03/memcached-install-python-use/#comments</comments>
		<pubDate>Mon, 14 Mar 2011 11:03:12 +0000</pubDate>
		<dc:creator>落落</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Memcached]]></category>

		<guid isPermaLink="false">http://liluo.org/?p=644</guid>
		<description><![CDATA[Memcached官网 memcached.org
简单介绍：memcached很强大，它可以支持分布式的共享内存缓存，大型站点都用它。对小站点来说，有足够内存的话，使用它也可以得到超赞的效果。
使用目的：由前面的介绍看到，大家使用它都是为了速度，不过我却是为了解决Session在不同浏览器中偶尔丢失的数据。其实也不能怪浏览器啦，主要是我需要一个dict类型的session，哈哈。
安装
Linux
安装包
对于大多数Linux发行版本来说，可以使用官方推荐的方法：
Debian/Ubuntu
apt-get install memcached
Redhat/Fedora/CentOS
yum install memcached
源码安装(CentOS 5.5)
1、下载libevent（依赖） 和memcached
分别到以下引用地址下载最新版本：
引用地址 http://www.monkey.org/~provos/libevent/ 
引用地址:http://code.google.com/p/memcached/downloads/list
2、安装ibevent（依赖） 和memcached
libevent(目前最新是libevent-2.0.10-stable.tar.gz，请注意版本号)
tar xvf libevent-2.0.10-stable.tar.gz
cd libevent-2.0.10-stable
./configure --prefix=/usr/local/libevent/
make
make install
接着，ls /usr/local/libevent/lib，将查看到的第一个类似libevent-X.X.so.X
ln -s /usr/local/libevent/lib/libevent-2.0.so.5  /lib/libevent-2.0.so.5
memcached (目前最新是1.4.5，请注意版本号)
tar zxvf  memcached-1.4.5.tar.gz
cd memcached-1.4.5
./configure --prefix=/usr/local/memcached --with-libevent=/usr/local/libevent/
make 
make install
3、启动memcached
启动参数说明(这是我是复制粘贴的，如有错误请指正)：
-d 选项是启动一个守护进程
-m 是分配给Memcache使用的内存数量，单位是MB，默认64MB
-M return error on memory exhausted (rather than removing items)
-u 是运行Memcache的用户，如果当前为root 的话，需要使用此参数指定用户
-l 是监听的服务器IP地址，默认为所有网卡
-p 是设置Memcache的TCP监听的端口，最好是1024以上的端口
-c 选项是最大运行的并发连接数，默认是1024
-P 是设置保存Memcache的pid文件
-f chunk size growth factor (default: 1.25)
-I Override the size of [...]]]></description>
		<wfw:commentRss>http://liluo.org/2011/03/memcached-install-python-use/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>【Lua101】类型和值</title>
		<link>http://liluo.org/2011/02/%e3%80%90lua101%e3%80%91%e7%b1%bb%e5%9e%8b%e5%92%8c%e5%80%bc/</link>
		<comments>http://liluo.org/2011/02/%e3%80%90lua101%e3%80%91%e7%b1%bb%e5%9e%8b%e5%92%8c%e5%80%bc/#comments</comments>
		<pubDate>Tue, 22 Feb 2011 11:10:43 +0000</pubDate>
		<dc:creator>落落</dc:creator>
				<category><![CDATA[Lua]]></category>

		<guid isPermaLink="false">http://liluo.org/?p=642</guid>
		<description><![CDATA[
作为动态语言的Lua有8个基本类型：nil、boolean、number、string、userdata、function、thread、table，使用type函数可以获取变量或者值的类型（这里和Python又是很类似）。依次来看下这8个基本类型（话说还有不基本的吗？先不管，慢慢看）：

1、Nil
Lua中特殊的类型，它的值就是nil；一个全局变量没有被赋值以前默认值为nil；给全局变量负nil可以删除该变量。（相当于None?不过貌似更强大）
2、Booleans
很熟悉的类型，有两个取值：false和true。需要注意的一点是，Lua中只有false和nil为假，其他包括0和空字符串都为真。
3、Numbers
这里叫作实数，没有int和float之分，包含了两者。
4、Strings
字符序列，lua是8位字节，所以字符串可以包含任何数值字符，包括嵌入的0。
可以使用单引号或者双引号表示字符串，还可以使用[[...]]表示字符串。这种形式的字符串可以包含多行也，可以嵌套且不会解释转义序列，如果第一个字符是换行符会被自动忽略掉，这种形式的字符串用来包含一段代码是非常方便的。
一个string可以只包含一个字母也可以包含一本书，Lua可以高效的处理长字符串，1M的string在Lua中是很常见的。Lua自动进行内存分配和释放。

a = "a line"
b = 'another line'

Lua转义序列：
\a bell
\b back space               -- 后退
\f form feed                -- 换页
\n newline                  -- 换行
\r carriage return          -- 回车
\t horizontal tab         [...]]]></description>
		<wfw:commentRss>http://liluo.org/2011/02/%e3%80%90lua101%e3%80%91%e7%b1%bb%e5%9e%8b%e5%92%8c%e5%80%bc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>【Lua101】开始热身——语法约定和命令行方式</title>
		<link>http://liluo.org/2011/02/%e3%80%90lua101%e3%80%91%e5%bc%80%e5%a7%8b%e7%83%ad%e8%ba%ab%e2%80%94%e2%80%94%e8%af%ad%e6%b3%95%e7%ba%a6%e5%ae%9a%e5%92%8c%e5%91%bd%e4%bb%a4%e8%a1%8c%e6%96%b9%e5%bc%8f/</link>
		<comments>http://liluo.org/2011/02/%e3%80%90lua101%e3%80%91%e5%bc%80%e5%a7%8b%e7%83%ad%e8%ba%ab%e2%80%94%e2%80%94%e8%af%ad%e6%b3%95%e7%ba%a6%e5%ae%9a%e5%92%8c%e5%91%bd%e4%bb%a4%e8%a1%8c%e6%96%b9%e5%bc%8f/#comments</comments>
		<pubDate>Sat, 12 Feb 2011 07:57:44 +0000</pubDate>
		<dc:creator>落落</dc:creator>
				<category><![CDATA[Lua]]></category>

		<guid isPermaLink="false">http://liluo.org/?p=638</guid>
		<description><![CDATA[话说看文字性的定义和注意事项最无聊了，所以就来大朵大朵的摘抄吧。
先来热身一下吧！
进入和退出交互环境
在命令行中输入lua回车就会以交互模式运行lua，键入文件结束符可以退出交互模式（Ctrl-D in Unix, Ctrl-Z in DOS/Windows），或者调用OS库的os.exit()函数也可以退出。

来看两个例子
如大多数语言一样，首先要写的就是著名的hello, world
在lua环境命令行输入
print("hello, world")
很眼熟吧，居然和Python3.x语法一样。
如果是把print("hello, world")保存在lua文件中，比如说使用lua filename.lua
再来看另外一个有点小复杂的例子，例子中首先定义一个是计算阶乘的函数，然后根据用户输入的数字输出结果。感叹一下，神似python那！
-- defines a factorial function
function fact (n)
if n == 0 then
return 1
else
return n * fact(n-1)
end
end
print("enter a number:")
a = io.read("*number")      -- read a number
print(fact(a)
Chunk是什么玩意？
Chunk是一系列语句，Lua执行的每一块语句（可以是一系列语句的组合，还可以是函数，Chunk可以很大，在Lua中几个MByte的Chunk是很常见的），比如一个文件或者交互模式下的每一行都是一个Chunk。
在交互模式下，Lua通常把每一个行当作一个Chunk，但如果Lua一行不是一个完整的Chunk时，他会等待继续输入直到得到一个完整的Chunk.在Lua等待续行时，显示不同的提示符（一般是&#62;&#62;）。
可以通过指定参数让Lua执行一系列Chunk。例如：假定一个文件a内有单个语句x=1；另一个文件b有语句print(x)
lua -la -lb
命令首先在一个Chunk内先运行a然后运行b。
运行完Chunk后进入交互模式则需要加上 -i 选项，如 lua -i -la -lb
除此之外，还可以使用dofile函数，在交互模式下：
dofile("test.lua")
然后就可以引用其中的函数等等。
-i和dofile很方便调试、测试代码。
语法约定
标示符：字母(letter)或者下划线开头的字母、下划线、数字序列.最好不要使用下划线加大写字母的标示符，因为Lua的保留字也是这样的。Lua中，letter的含义是依赖于本地环境的。
保留字 ：以下字符为Lua的保留字，不能当作标识符。
and        break      do         else         elseif
end        false        for        function   if
in           local        nil         not          or
repeat    return     then [...]]]></description>
		<wfw:commentRss>http://liluo.org/2011/02/%e3%80%90lua101%e3%80%91%e5%bc%80%e5%a7%8b%e7%83%ad%e8%ba%ab%e2%80%94%e2%80%94%e8%af%ad%e6%b3%95%e7%ba%a6%e5%ae%9a%e5%92%8c%e5%91%bd%e4%bb%a4%e8%a1%8c%e6%96%b9%e5%bc%8f/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>【Lua101】准备工作</title>
		<link>http://liluo.org/2011/02/%e3%80%90lua101%e3%80%91%e5%87%86%e5%a4%87%e5%b7%a5%e4%bd%9c/</link>
		<comments>http://liluo.org/2011/02/%e3%80%90lua101%e3%80%91%e5%87%86%e5%a4%87%e5%b7%a5%e4%bd%9c/#comments</comments>
		<pubDate>Thu, 10 Feb 2011 02:43:07 +0000</pubDate>
		<dc:creator>落落</dc:creator>
				<category><![CDATA[Lua]]></category>

		<guid isPermaLink="false">http://liluo.org/?p=634</guid>
		<description><![CDATA[学习Lua就从这里开始啦。
首先来了解一下吧 Lua(百度百科)
其次需要准备的就是下载安装了。 
Linux 
1、从Lua的官网（http://www.lua.org/）下载最新版本；
2、使用tar -xzvf 命令解压，产生一个lua-5.1.x目录(我这里是5.1.4)；
3、切换到2中的目录，即cd lua-5.1.4；
4、运行make命令，显示信息如下：
Please do
make PLATFORM
where PLATFORM is one of these:
aix ansi bsd freebsd generic linux macosx mingw posix solaris
See INSTALL for complete instructions.
主要是lua支持系统平台的列表，linux则运行make linux
5、运行make install命令。
到这里，lua语言环境已经顺利安装完成，在终端下输入lua命令即可进入。
Win
1、访问 http://luaforge.net/frs/?group_id=377 ；
2、下载.exe文件、安装，（附带了编辑器，连环境变量都顺带搞定）。
至此，所有准备工作已经完成。另外再加点料：
官方网站 http://www.lua.org
国内社区  http://www.luaer.cn/
Lua手册（半中文版） http://manual.luaer.cn/
Lua程序设计（第2版，中文） http://book.luaer.cn/
]]></description>
		<wfw:commentRss>http://liluo.org/2011/02/%e3%80%90lua101%e3%80%91%e5%87%86%e5%a4%87%e5%b7%a5%e4%bd%9c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>python操作Excel读写(使用xlrd和xlrt)</title>
		<link>http://liluo.org/2011/01/python%e6%93%8d%e4%bd%9cexcel%e8%af%bb%e5%86%99%e4%bd%bf%e7%94%a8xlrd%e5%92%8cxlrt/</link>
		<comments>http://liluo.org/2011/01/python%e6%93%8d%e4%bd%9cexcel%e8%af%bb%e5%86%99%e4%bd%bf%e7%94%a8xlrd%e5%92%8cxlrt/#comments</comments>
		<pubDate>Fri, 07 Jan 2011 13:03:14 +0000</pubDate>
		<dc:creator>落落</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Excel]]></category>
		<category><![CDATA[xlrd]]></category>
		<category><![CDATA[xlwt]]></category>

		<guid isPermaLink="false">http://liluo.org/?p=629</guid>
		<description><![CDATA[传说中python操作ms office功能最强大的是win32com（据说只要人工能操作的它都能实现，未尝试尚不知道真假），不过对于比较简单的需求显得有些小题大作。那么来看下简单的，分别是xlrd和xlwt模块。
xlrd
http://pypi.python.org/pypi/xlrd
简单使用

导入
import xlrd
打开excel
data = xlrd.open_workbook('demo.xls') #注意这里的workbook首字母是小写
查看文件中包含sheet的名称
data.sheet_names()
得到第一个工作表，或者通过索引顺序 或 工作表名称
table = data.sheets()[0]
table = data.sheet_by_index(0)
table = data.sheet_by_name(u'Sheet1')
获取行数和列数
nrows = table.nrows
ncols = table.ncols
获取整行和整列的值（数组）
table.row_values(i)
table.col_values(i)
循环行,得到索引的列表
for rownum in range(table.nrows):
print table.row_values(rownum)
单元格
cell_A1 = table.cell(0,0).value
cell_C4 = table.cell(2,3).value
分别使用行列索引
cell_A1 = table.row(0)[0].value
cell_A2 = table.col(1)[0].value
简单的写入
row = 0
col = 0
ctype = 1 # 类型 0 empty,1 string, 2 number, 3 date, 4 boolean, 5 error
value = 'lixiaoluo'
xf = 0 # 扩展的格式化 [...]]]></description>
		<wfw:commentRss>http://liluo.org/2011/01/python%e6%93%8d%e4%bd%9cexcel%e8%af%bb%e5%86%99%e4%bd%bf%e7%94%a8xlrd%e5%92%8cxlrt/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>CPS系统开发(PyLons项目)</title>
		<link>http://liluo.org/2010/12/cps%e7%b3%bb%e7%bb%9f%e5%bc%80%e5%8f%91pylons%e9%a1%b9%e7%9b%ae/</link>
		<comments>http://liluo.org/2010/12/cps%e7%b3%bb%e7%bb%9f%e5%bc%80%e5%8f%91pylons%e9%a1%b9%e7%9b%ae/#comments</comments>
		<pubDate>Fri, 17 Dec 2010 11:04:55 +0000</pubDate>
		<dc:creator>落落</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Pylons]]></category>

		<guid isPermaLink="false">http://liluo.org/?p=622</guid>
		<description><![CDATA[最近在埋头写CPS系统，到现在为止程序开发已经全部完成，剩下的由美工来设计页面和CSS（感觉很奇怪吧，项目开发完了才来这项？没办法，公司小，老板又不肯听解释）。嗯，系统和GPS只差一个字母，好玩吧？其实没有，一点也不好玩。 
CPS中文就是职业定位系统，是现在公司目前的主要业务，目前使用的版本是公司股东那边负责使用java开发的　（地址http://cps.hbbcareer.com界面很纠结是吧？哈哈，当时是由我乱拼出来的）。简单的来描述一下系统流程就是：首先由某公司或者个人买单，然后测评用户做选择题，然后得到一份报告，内容就是个人优势劣势分析，主观认知与客观事实的差异以及匹配的行业和职业。当然了，这样来讲似乎太简化了，嘿嘿。
系统依然是使用Python开发（其他我也不会……），其中：
服务器CentOS5.5
数据库Postgresql 9.0
Web Server: Nginx 8.49
Python版本 　2.6.5
Framework　　PyLons 1.0
Template　　 mako
Excel读写　　xlrd、xlwt
生成图表　　matplotlib
对图片操作　Pil
生成PDF　　reportlab
在线支付使用网银在线，参照其PHP版本的接口改写成Python版本
项目中费时最多的就是图表和PDF文档的生成，其中中文字符、字号大小，格式排版等问题有点小纠结，不过掌握之后觉得也蛮简单，这几天抽出时间总结一下对Excel读写操作的xlrd,rlwt以及matplotlib和reportlab的基本使用。
最后放张缩略图

]]></description>
		<wfw:commentRss>http://liluo.org/2010/12/cps%e7%b3%bb%e7%bb%9f%e5%bc%80%e5%8f%91pylons%e9%a1%b9%e7%9b%ae/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>单元测试(python\django\pylons)</title>
		<link>http://liluo.org/2010/11/pythondjangopylons-%e5%8d%95%e5%85%83%e6%b5%8b%e8%af%95/</link>
		<comments>http://liluo.org/2010/11/pythondjangopylons-%e5%8d%95%e5%85%83%e6%b5%8b%e8%af%95/#comments</comments>
		<pubDate>Thu, 25 Nov 2010 09:44:09 +0000</pubDate>
		<dc:creator>落落</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Pylons]]></category>
		<category><![CDATA[Unit]]></category>
		<category><![CDATA[单元测试]]></category>

		<guid isPermaLink="false">http://liluo.org/?p=614</guid>
		<description><![CDATA[清风老师提到的第2点——单元测试，总结一下。
其实我的主要目的是想Django的单元测试，由于Django使用了Python的标准模块doctest和unittest，所以我觉得有必要了解一下Python的单元测试。另外还有就是比较欣赏的PyLons框架的单元测试内容。
一、Python单元测试doctest,unittest（PyUnit） 
1、doctest 框架 
在Python中doctest就是把程序中的docstring作为范例来运行的一个框架，docstring可以由普通部分和执行部分组成，普通部分等同于原来的文字说明，执行部分由'&#62;&#62;&#62;'（python shell提示符）或'...'提示符区分。程序员可以通过手工编写可预测的执行部分，也可以通过拷贝复制python交互式shell中的输入和输出简单的形成执行部分，doctest搜寻存在与各个模块，类和函数中的docstring,把每个可执行部分当成一次范例运行，再把实际运行值和期望值的对照作为一次运行结果。
我大致看了一下doctest，感觉还是比较容易上手的，另外还有一个优点就是可以很方便的生成文档。由于比较简单，就不多作介绍，具体可参考：
http://docs.python.org/library/doctest.html
2、unittest(PyUnit框架)
unittest模块,也就是PyUnit（全称：The Python unit testing framework）是Kent Beck和Erich Gamma这两位聪明的家伙所设计的 JUnit 的Python版本，自从Python2.1版本以后，PyUnit已经被加入到Python标准库（也就是unittest）。
简单实例：
import unittest            # 导入单元测试模块
from demo import Demo
class DemoTests(unittest.TestCase):  # 由TestCase派生类
def setUp(self): # 开始单元测试准备工作，初始化环境
pass
def tearDown(self): # 完成单元测试收尾，清除环境
pass
def testAdd(self): # 完成单元测试收尾，清除环境
pass
def suite():
suite = unittest.TestSuite()
suite.addTest(Demo('testAdd'))
return suite
if __name__ == "__main__":
unittest.TextTestRunner().run(suite())
参考：
http://docs.python.org/library/unittest.html
http://pyunit.sourceforge.net/pyunit_cn.html
二、Django单元测试  
Django中的单元测试有2种:Doctests、Unit tests，分别对应Python标准库doctest和unittest，可想而知其用法也是大同小异。
1、Doctests
对于一个Django应用程序，它会在应用程序目录下的models.py和tests.py两个文件去寻找可运行的doctests。需要注意的是，在models.py的doctest当中，test runner自己会建立单独的测试用数据库。也就是说，任何涉及数据库访问的测试——如创建并保存了模型的实例——都不会对你实际使用的数据库产生影响，因为测试时会使用它自己创建的单独的数据库。同时，在doctests运行期间，你实际使用的数据库也不会刷新。所以，如果你的测试依赖于一些特定的状态，那么你就应该考虑显式操作你实际使用的数据库，或者读取一个fixture（伪造的可用数据）。（后面会有关于fixtures更详细的介绍。）请注意，要使用此功能，作为数据库用户的Django必须要有可 CREATE DATABASE 的权限。
如果感觉 doctest 更显得 “pythonic”（它的设计目的本来就是使编写测试尽可能的简单化，而不用专门去写一些类，函数之类的东西。你只需要像写注释一样把测试功能写在docstrings里就可以了。这种做法的一个额外好处，就是测试可以直接作为文档的一部分）或者如果是刚刚接触测试工作的人，那么使用doctests会更快地入门单元测试。
关于doctest细节，同样可参考 http://docs.python.org/library/doctest.html
2、Unit tests
相较于doctests，unit tests使用了另外一种方式定义测试，一种基于“类”的实现。像doctests一样，对于一个Django应用程序，test runner会在两个地方寻找unit tests：应用程序目录下的models.py和tests.py。运行测试 时，测试工具默认的行为是在 models.py 和 tests.py 中找到所有的测试用例（ unittest.TestCase 的所有子类），然后自动将这些测试用例构建成一个测试集，然后开始跑这个测试集。
如果在 models.py 或 tests.py 中定义了一个名为 suite() 的函数，那么Django的test runner将会调用此函数来构建本模块的测试集。这也是被 推荐使用 的测试用例的组织方法。
关于unit [...]]]></description>
		<wfw:commentRss>http://liluo.org/2010/11/pythondjangopylons-%e5%8d%95%e5%85%83%e6%b5%8b%e8%af%95/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>

