2012年11月28日星期三

python: 转换被错误定义为unicode类型的utf-8编码

某同事的代码中发现,本来是utf-8编码的字符串,从数据库读出来后,被错误返回为u'utf-8内码'这样的格式。

下面是一个简单的转换方法,还原其为正常的utf-8编码:

>>> a = '测试'
>>> a
'\xb2\xe2\xca\xd4'
>>> b = a.decode('gbk').encode('utf-8')
>>> b
'\xe6\xb5\x8b\xe8\xaf\x95'
>>> c = u'\xe6\xb5\x8b\xe8\xaf\x95'
>>> c
u'\xe6\xb5\x8b\xe8\xaf\x95'
>>> arr = array.array('B')
>>> arr.fromlist([ord(i) for i in c])
>>> print arr.tostring().decode('utf-8').encode('gbk')
测试 

最终的代码是这样:
import string
import array
s = u' \xe6\xb5\x8b\xe8\xaf\x95 '
arr = array.array('B')
arr.fromlist([ord(i) for i in s])
print arr.tostring().decode('utf-8').encode('gbk')

如果读者知道更好的转换方法,希望不吝赐教。

2012年11月27日星期二

安装python图标库pycha搞得很郁闷

根据帖子推荐,发现pycha是所有python图标库中比较简单的,于是打算采用这个。
结果,安装这个库花了我两个半天,仍未能解决,打算放弃。

1. 首先在pycha的首页https://bitbucket.org/lgs/pycha/wiki/Home找下载地址。
   找了半天居然没有,只有个项目管理软件hg的地址。
   好吧,先安装windows下的hg客户端。
2. 安装hg客户端:
  http://cdn.bitbucket.org/tortoisehg/files/downloads/tortoisehg-2.6.0-hg-2.4-x86.msi
3. 使用hg下载源码:
  hg clone http://bitbucket.org/lgs/pycha
4. 安装上了没效果,原来还需要库 cairo。于是下载cairo
  http://www.cairographics.org/releases/py2cairo-1.10.0.tar.bz2
5. cairo库不同于一般python库的安装,居然还需要python的头文件,于是再下载python源码包来编译:
    http://www.python.org/ftp/python/2.7/Python-2.7.tgz
6. 再编译cairo,指定头文件的路径,仍然编译不通过……

选择一个不成熟的库,果然很折腾啊!





2012年11月26日星期一

评《技术含量的问题》

原帖请见:http://www.dbanotes.net/review/Tech_Simple.html

不是很赞同冯大辉的观点。

    不重视技术问题,因技术的成本高转而采用人工;或者是技术成熟度没达到人工水准,继续采用人工——这些只能在一个特定的阶段来使用。
    比如,公司刚刚成立,还处理生存的压力下,无可厚非。
    而对于一个已经起步的公司,这样做无疑饮鸩止渴:

1. 这是技术债务,总有一天要还的。
   借来的钱一开始用得很爽,等到要还债的时候,就会变得痛苦。

2. 某技术当前阶段的发展不如人工,但不代表它永远都无法超越人工的水平。
   现在不去积累,失去了先机,放弃了成为技术壁垒的决心……等到它成熟的时候,你已经再也没机会去捡起来了。

3. 廉价的人力资源也是资源,随着环境的变化,它慢慢也会成为稀缺资源。
   当前珠三角的用工荒,已经说明了这个问题。

  因此,特别是大公司,应该在某些技术领域投入资源去进行攻关。如果总是以为没技术含量的手段也能解决问题,技术债务总有一天会令它头破血淋。

2012年10月25日星期四

小记:解决mysql机器上的单CPU过高

最近某一mysql机器有告警,显示单CPU占用常常超过90%。
奇怪的是,机器上4个CPU,仅CPU 0的占用较高,而其他三个CPU很闲。

继续检查发现,CPU 0的占用高,主要都花在iowait上。
可是,即便是IO高,也应该每个CPU的IOWAIT都高,毕竟mysqld是一个多线程服务器。

为了验证这点,输入:top,按f,按j,按空格,按shift+h——查看每个线程的执行情况,并显示该线程正在哪个CPU上执行。

观察发现,mysqld的线程几乎都在cpu 0上执行,难怪CPU 0的占用高。
于是简单地写个脚本来分担CPU 0的压力:

vi set_mysqld_cpu_affinity.sh
#!/bin/bash


v_list=`ps -Lf -C mysqld h| awk '{print $4}'`
for p in $v_list
do
        taskset -cp 1,2,3 $p
done

执行后CPU的IO WAIT都变得比较平均了。

2012年10月10日星期三

想要家庭版的照片云服务软件

有没有这种一种家庭版的照片云服务软件,支持酱紫的功能:
1. 各种终端可以自动通过WIFI同步最新拍照的照片;
2.自动根据拍照时间和地理位置建立索引;
3. 自动识别横竖;
4. 去重,始终不会存储同样的图片;
    如果A图是B图的一个子集,则A图只需要很小的存储空间即可
5. 海量存储;
6.自动生成各种规格的缩略图,可快速浏览大量的图片;智能识别终端,总是输出合适的大小。
7. 按照色彩搜索:选择某种简单的色调,或者模糊定义色彩丰富和色彩单调
8. 相似照片归类:根据16*16的缩略图的二进制相似算法来对图片进行聚类
9. 比较基本的功能:文字备注,按备注文字搜索
10. 进一步:语音备注,语音识别
11. 涂鸦:在触摸屏上对照片写写画画能保存下来,而且能识别是哪个家庭成员的涂鸦
12. 人脸识别,按照人脸聚类
13. 先对图片高斯模糊,提取特征,然后按照特征进行聚类。
    比如有山的图片和有海的图片会归类到一起。
14. 照片中的文本识别:照片中出现字母或数字,能够被搜索出来。

===========================================
2012-10-15续:
配合家庭使用的文件存储服务器,家庭版的照片处理云服务会大有可为,这可能是一个比较热门的细分市场:
1. 手机、数码相机、数码摄像机等设备的价格降低和兴起,必然使得一个家庭在日积月累中产生大量的照片和视频;
2. 由于中国的网络带宽的限制,不太可能把那么多的照片都上传到网络上共享,且用户还担心隐私的问题;
3. 如何快速找到想要的照片?独特的照片搜索将会让用户更加离不开家庭版的云服务。

2012年9月14日星期五

python PIL: 图片的倒影效果的简单实现

具体的算法就是把图片的每一行对称翻转,然后将透明度从低到高逐行设置。
见代码:


import sys,os
from PIL import Image

if __name__=='__main__':
    argc = len(sys.argv)
    if argc<3:
        print 'usage:%s <file> <dest>'%sys.argv[0]
        sys.exit(-1)
    im = Image.open(sys.argv[1]).convert('RGBA')
    arr = []
    (w,h) = im.size
    x = 0
    y = 0
    index = 0
    arr_row = []
    for pixel in im.getdata():
        pixel = list(pixel)
        x = index % w
        y = index / w
        index += 1
        pixel[3] = int(256.0*0.2*(float(y)/float(h)))
        arr_row.append(tuple(pixel))
        if index%w==0 and index>0:
            arr = arr_row + arr
            arr_row = []
    #
    im1 = Image.new('RGBA', (w,h))
    im1.putdata(arr)
    im1.save(sys.argv[2])

原图和效果见下面:


复习:多阶hash表

关于多阶hash表的具体代码实现,请移步到:《使用共享内存的多级哈希表的一种实现》http://webcache.googleusercontent.com/search?q=cache:GEiOeyiYdXEJ:www.cppblog.com/lmlf001/archive/2007/09/08/31858.html+&cd=2&hl=zh-CN&ct=clnk

本文主要讲多阶HASH表的结构。

1. 多阶hash表实际上是一个锯齿数组,看起来是这个样子的:
■■■■■■■■■■■■■■■
■■■■■■■■■■■■■
■■■■■■■■■■
■■■■■■
■■■

每一行是一阶,上面的元素个数多,下面的元素个数依次减少。
每一行的元素个数都是素数的。

2. 数组的每个节点用于存储数据的内容,其中,节点的前四个字节用于存储int类型的key或者是hash_code

3. 创建多阶HASH的时候,用户通过参数来指定有多少阶,每一阶最多多少个元素。
那么,下面的每一阶究竟应该选择多少个元素呢?从代码注释上看来,是采用了素数集中原理的算法来查找的。
例如,假设每阶最多1000个元素,一共10阶,则算法选择十个比1000小的最大素数,从大到小排列,以此作为各阶的元素个数。通过素数集中的算法得到的10个素数分别是:997 991 983 977 971 967 953 947 941 937。
可见,虽然是锯齿数组,各层之间的差别并不是很多。

4. 查找过程:

   先将key在第一阶内取模,看是否是这个元素,如果这个位置为空,直接返回不存在;如果是这个KEY,则返回这个位置。
   如果这个位置有元素,但是又不是这个key,则说明hash冲突,再到第二阶去找。
   循环往复。


5. 好处:
  1. hash冲突的处理非常简单;
  2. 有多个桶,使得空间利用率很高,你并不需要一个很大的桶来减少冲突。
  3. 可以考虑动态增长空间,不断加入新的一阶,且对原来的数据没影响。
整理后的源码在此:https://docs.google.com/open?id=0B2ZH5H4iY-oLSXdPSDVoVFBoSVU