ColaPHP 0.5beta发布

January 24th, 2010

ColaPHP的第一个beta版本,代号:Practice,已经实践的优化,可以适量应用在实际项目中,相比较0.4alpha,比较大的修改如下:

  • 增加字符串加密助手,支持XOR、mcrypt加密,支持混淆
  • 增加分页类
  • 重构了HTTP请求类,可定制性更强
  • 重构了Validate类,增加批量校验
  • 其他代码重构以及bug fix

下载ColaPHP 0.5beta,阅读ColaPHP文档,访问ColaPHP项目

下一个版本0.6beta开发代号:Easy,将在易用性方面进一步优化。

Tags:

MongoDb In Action

January 23rd, 2010

This slide will tell you how to use MongoDb as MySQL in your application.

Tags: ,

Python处理MP3的歌词和图片

January 21st, 2010

一些MP3播放器(包括iphone、ipod、itouch、blackberry等)可以在播放mp3的时候显示专辑图片、歌词等信息而不需要额外的图片文件和歌词文件,仅仅一个mp3文件就搞定,比较有意思。除了用专门的软件(比如itunes)来制作这样的mp3,我们还可以用程序来批量生成。

查阅mp3头信息ID3V2的技术文档,发现可以往ID3信息里面加入歌词和图片信息(可以在页面上查找Lyrics、Attached picture就能发现相应的内容)。有了官方格式上的支持,我们要做的就是把歌词和图片加入到MP3文件中去。

测试一些开源的软件包,发现一个比较可靠的:eyeD3,由python语言编写,直接上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#coding=utf-8
import eyeD3
import re
 
# mp3文件
mp3_file = '/path/to/foobar.mp3'
# lrc歌词文件
lrc_file = '/path/to/foobar.lrc'
# 专辑图片
pic_file = '/path/to/foobar.jpg'
 
# 实例化eyeD3
tag = eyeD3.Tag()
 
# 绑定到mp3文件
tag.link(mp3_file)
 
# 去掉原文件中可能存在的图片
tag.removeImage()
 
# 去掉原文件中可能存在的歌词
tag.removeLyrics()
 
# 设定编码,非常重要,否则不支持中文
tag.encoding = '\x01'
 
# 添加图片
tag.addImage(3, pic_file, u'')
 
# 添加歌词,注意要utf-8编码,去掉lrc中时间信息
tag.addLyrics(re.sub('(\[.*?\][\n]*)+', '', unicode(open(lrc_file, 'r')).read(), 'utf8')))
 
# 更新到文件
tag.update()

代码非常简单,需要注意的是设定编码,不然歌词就乱码了。有了eyeD3之后,可以写个爬虫,从网上抓下歌词和图片直接灌进MP3文件里面,剩下的就是享受了。

Tags: , , , ,

还在路上

December 31st, 2009

又是一年算账的时候,去年的今天写了2009年的一些计划:网络(socket)/桌面(gui)编程;一个精巧的PHP框架;数据挖掘;多一些好朋友。socket/gui编程算是稍稍入门吧;PHP框架(ColaPHP)已经发了4个alpha版本,目前从实际项目中看表现还可以,可能下一个版本就进入beta阶段,beta意味着ColaPHP逐步趋于稳定;数据挖掘前半年做的比较多,进展不算太大;好朋友多了一些,此事甚为欣慰。

2009年技术上主要是代码方面的成长,重构的事情做的比较多,已不太相信过于花哨的玩意。脾气方面,”骄躁”二字少了些。回过头来看2009,不觉太多收获,亦不觉浮度。

2010年想要做的一些事情:学一门新语言;ColaPHP发一个GA版本;数据挖掘,做一个开源的推荐系统;更多的好朋友。

希望春天能在2010年到来。

ColaPHP-0.4-alpha发布

December 23rd, 2009

ColaPHP月度发布计划,基本上每月发一个release,相比较0.3alpha,比较大的修改如下:

  • 增加了动态路由模式,可不用定义URL规则
  • 增加对MySQL Master-Slave支持,可以由单数据库无缝迁移到主从模式
  • 去除框架中Smarty模板的绑定,可以在Controller中自行调用Smarty模板
  • Helper中增加了性能测试模块Benchmark.php
  • 增加对MongoDB的简单绑定Mongo.php
  • 性能进一步提升
  • 大量的代码重构以及bug fix

访问ColaPHP官方网站,下载0.4alpha,不过建议随时跟进我们的svn://colaphp.googlecode.com/svn/trunk/,ColaPHP一直在活跃开发。

ColaPHP 0.4alpha已完成预期目标,所有的函数都控制在20行以内。下一个版本0.5alpha版本开发代号:Practice,ColaPHP已经在一些实际项目中使用,0.5alpha将得到更多的实践优化

招募PHP极客加入ColaPHP,联系fuchaoqun#gmail.com。

Tags: ,

[视频] Music Recommender Systems

November 29th, 2009

上次去beta沙龙的视频,希望没有浪费大家的时间,感谢beta沙龙的组织工作。

Tags: , , , ,

Music Recommender Systems

November 17th, 2009

周末beta沙龙和大家分享的音乐智能推荐PPT,有些内容和上次的PPT差不多,这次主要和大家分享一个完整的数据挖掘流程,同样的,还是工程方面比较多,学术方面这里有很多大牛。

Tags: , , , , ,

从140秒到2秒的优化

November 12th, 2009

从2亿个0~2,000,000,000之间的数字样本中找出不重复的记录总数,首先想到的是bloom filter,转念一想既然全都是数字,bloom filter有点太重,bitarray也许更有效,于是第一个版本出来,部分代码如下:

ba = bitarray(212**4)
cnt = 0
for i in data:
    if (not ba[i]):
        cnt += 1
        ba[i] = True
print cnt

大概需要140s左右,觉得if (not ba[i]):这个比较费,改了第二版:

for i in data:
    ba[i] = True
print ba.count()

速度有所提升,到了120s左右,开始打起多核运算的主意了,山寨了一个map-reduce,首先通过maper把数据按照除4得余分成4份:

def maper(data):
    map_data = (array('I'),array('I'),array('I'),array('I'))
    for i in data:
        m = i % 4
        map_data[m].append(i)
    return map_data

然后起了一个4个进程的woker pool分别计算,最后把结果汇总:

def worker(data):
    counter = bitarray(256**4)
    for i in data:counter[i] = True
    return counter.count()
 
p = Pool(4)
result = p.map(worker, data)

速度提高明显,到了50s左右,这个做法的问题是两次遍历:map的时候一次、reduce的时候又一次,于是开始想办法解决,把文件直接分开运算,不再map,把最后的结果做一下位或再计数:

p = Pool(4)
result = p.map(worker, data)
print (result[0] | result[1] | result[2] | result[3]).count()

到了26s左右,可能Python在进程间交换大数据量效率不是太好,再优化的空间有限,想起之前用Python的科学运算库做过数据挖掘,能不能用那个库试试,于是有了NumPy的版本:

import numpy as np
print len(np.unique(np.fromfile('/path/to/data.dat', np.uint32)))

全部程序就这两行,速度到了12s,让人崩溃,NumPy的底层大多是C的实现,对代码做了一个profile,发现NumPy用了sort,有点浪费,如果我用C实现一部分功能的话效果应该会不错,注意到代码中有for i in data,data中有2亿条,就循环调用了2亿次,尝试把这个调用都封装在C里面,使用C级别的循环,于是用C扩展了一下bitarray包:

static PyObject *
bitarray_fromarray(bitarrayobject *self, PyObject *pyo)
{
    unsigned int *l;
    idx_t n1;
    Py_ssize_t nbytes, nitems, i;
    if (PyObject_AsReadBuffer(pyo, (const void **)&l, &nbytes) != 0)
        return Py_False;
    nitems = nbytes/sizeof(unsigned int);
    for (i=0; i<nitems; i++) {
        *(self->ob_item + l[i] / 8) |= ((char) 1) << (l[i])%8;
    }
    n1 = count(self);
    return PyLong_FromLongLong(n1);
}

直接读取文件buffer到bitarray,python程序就变成了:

from bitarray import bitarray
counter = bitarray(212 ** 4)
fp = open('/path/to/data.datbk', 'rb')
un = counter.fromarray(fp.read())
print un

一共5行代码,速度到了2s内,收工。

Tags: ,

ColaPHP-0.3-alpha发布

November 7th, 2009

开发工作很久以前就基本完成了,一直没来得及整理,今天发布0.3alpha,相比较0.2alpha,比较大的修改如下:

  • Helper中增加了验证码模块Captcha.php、HTTP访问模块Http.php、数据校验模块Validate.php
  • 修订DB模块中result($sql)函数,如果$sql是select语句则返回结果集,如果是insert语句则返回最后插入ID,如果是update或者delete语句,则返回受影响行数(有可能为0行),其他语句则返回query句柄
  • 完善框架的易用性:增加了统一配置文件;可以指定models、views、controllers目录;支持默认模版名称
  • 大量的代码重构以及bug fix

下载0.3alpha,不过建议随时跟进我们的SVN://colaphp.googlecode.com/svn/trunk/,ColaPHP一直在活跃开发。

0.4alpha版本开发代号:20 lines,目标是把所有的函数都控制在20行以内以及代码的持续重构。

继续招募PHP极客加入Cola,联系fuchaoqun#gmail.com。

Tags:

jQuery表单校验

November 2nd, 2009

最近有个项目,用到很多的表单校验,尝试了一下jQuery.validator,甚是顺手,地址:http://plugins.jquery.com/project/validate,基本的用法:

$('#formId').validate({
    debug:true, // 打开debug模式,不会真实提交,适合测试
    rules:{
        uName:"required", // 需要录入
        uNick:{
            required:true
        }, // 需要录入的另一种写法
        uBlog:{
            required:true,
            url:true
        } // 需要输入,且录入的必须是url
    },
    messages:{ // 自定义提示语文字
        uName:"请输入用户名"
    },
    submitHandler:function(form) { // 表单提交,需要jqueyr.form插件
        form.submit();
    }
}

阅读一下文档差不多就会了解,支持的校验格式有:

required:必填字段

email:电子邮件

url:合法的网址

date:日期

dateISO:日期(ISO)

number:数字

digits:整数

creditcard:信用卡号

equalTo:相同的值

accept:拥有合法后缀名的字符串

maxlength:最多长度的字符串

minlength:最少长度的字符串

rangelength:一个长度介于最小值和最大值之间的字符串

range:一个介于最小值和最大值之间的值

max:最大值

min:最小值

相对高阶一点功能:

  • 自定义错误提示信息

    当然,你可以通过定义messages来修改提示信息,但你想偷懒又不想用默认的英文提示,直接引入默认提示文字

    <script src="path/to/localization/messages_cn.js" type="text/javascript"></script>
  • IE6下不工作的bug

    传闻IE6下,jquery.validate.js有乱码,不能正常工作,解决办法:

    <script src="path/to/jquery.validate.js" type="text/javascript" charset="iso-8859-1"></script>
  • 控制错误信息显示位置

    有的时候默认的错误信息显示有问题,比如多个单选框,默认的会把错误信息显示在第一个单选框后面,页面就乱了,解决办法:

    errorPlacement: function(error, element) {
        if (element.is(":radio")) {
            error.appendTo(element.parent().parent("td"));
        else {
            error.appendTo(element.parent());
        }
    }

    当然,还可以重载invalidHandler来实现

  • 依赖校验

    有的时候,一个输入框的校验依赖于其他条件,比如登录的时候可以通过用户名或者邮箱登录,只有当用户选择用邮箱登录时,才对邮箱输入框验证,rules中可以这样写:

    uMail:{
        required:{depends: function(element) {
            return true == $('#isMail').val();
        }},
        email:true
    }

    这样只有用户选择了用邮箱登录才会校验 邮箱项,否则不校验。

Tags: ,