5月 15

centos 6.5 下编译测试pypy2.3

  编译环境使用dell服务器,CPU主频2.6GHz,内存32G,操作系统使用CentOS6.5 64位,python为2.7。简单操作记录如下。

yum install gcc* make libffi libffi-devel expat expat-devel \
       bzip2 bzip2-devel libncurses-devel libssl-dev libgc-dev
wget https://bitbucket.org/pypy/pypy/downloads/pypy-2.3-src.tar.bz2
tar jxvf pypy-2.3-src.tar.bz2
mv pypy-pypy-394146e9bb67 /usr/local/pypy
cd /usr/local/pypy
python rpython/bin/rpython -Ojit pypy/goal/targetpypystandalone.py

  耐心等待一个多小时(104m56.034s)编译完成。到pypy目录下看到pypy-c的可执行文件。

rpyhon 编译参数
-O : 编译为字节码后的优化级别。默认为2,此处使用的jit。

级别说明:
0 – 关闭优化功能,编译速度最快。使用的是系统垃圾回收器(Debian package libgc-dev)。0和1级别外都是使用的内置垃圾回收器。0和1运行速度会非常慢。
1 – 使用非耗时的优化
size – 最大限度的减小可执行文件的体积
mem – 最大程度减小内存消耗
2 – 开启所有优化,获得好的运行性能
3 – 同2类似,使用gcc重新编译pypy部分。
jit – 开启所有优化,使用jit即时编译器。jit是将字节码转换成可以直接发送给处理器的指令的程序。

  编译是单核进行的,所以多核是没有意义,如果想快就要主频高,内存高。如果是用云主机2G内存的话估计要一、两天时间。
  注:操作系统CentOS 6.3编译有问题。具体问题没有详细查。
  计算速度测试代码位置http://www.simonzhang.net/?p=1844
  使用python运行 14.9753940105秒,pyp运行3.56524395943秒。

  安装pip,后用pip安装tornado和flask框架。

tornado测试代码

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")

application = tornado.web.Application([
    (r"/", MainHandler),
])

if __name__ == "__main__":
    application.listen(5000)
    tornado.ioloop.IOLoop.instance().start()

flask测试代码

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello World!'

if __name__ == '__main__':
    app.run(host='192.168.6.250')

  为了方便使用将命令放到系统环境中。
ln -s /usr/local/pypy/pypy-c /usr/local/bin/pypy
ln -s /usr/local/pypy/bin/pypy-c /usr/local/bin/pip

参考网页
http://pypy.readthedocs.org/en/latest/config/opt.html

3月 31

用户自行修改svn密码的简单服务

svn做好,最基础的使用方法。将来用户要修改密码或忘记密码总要来问还是挺麻烦。不想处理这种简单问题。所以在python+tornado的框架上写了个页面,直接python跑起来。省了自己不少的事。

#!/bin/python
#-*- coding:utf-8 -*-
# Filename:    websvn.py
# Revision:    
# Date:        2014-03-27
# Author:      simonzhang
# web:         www.simonzhang.net
# Email:       simon-zzm@163.com
### END INIT INFO

import tornado.ioloop
import tornado.web

import smtplib
from email.mime.text import MIMEText 

from string import strip

# base set
webport = '88'
passfile = '/program/svn/conf/passwd'
# svn start comm
svn_start_comm = '/program/svn/bin/svnserve -d -r /program/svn/ --listen-port 59999'
# use send user info
mail_host = 'smtp.simonzhang.net'
mail_user = 'test@simonzhang.net'
mail_pwd = '123456'

def mail_send(content, mailto):
     msg = MIMEText(content.encode('utf8'), _subtype='html',  _charset='utf8')
     msg['From'] = mail_user
     msg['Subject'] = u'svninfo'
     msg['To'] = mailto
     try:
         s = smtplib.SMTP()
         s.connect(mail_host)
         s.login(mail_user,mail_pwd)
         s.sendmail(mail_user,[mailto],msg.as_string())
         s.close()
     except Exception ,e:
         print e 

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        index_html = '''
用户名 老密码 新密码 再次输入
用户邮箱
''' self.write(index_html) class EditPassHandler(tornado.web.RequestHandler): def get(self): # 清理临时文件 try: import os os.remove('%s.tmp' % passfile) except: pass # 是否重启的状态 reboot_status = 0 user = strip(self.get_argument('user')) oldpass = strip(self.get_argument('oldpass')) newpass1 = strip(self.get_argument('newpass')) newpass2 = strip(self.get_argument('newpass2')) if (len(user) == 0) or (len(oldpass) == 0) or \ (len(newpass1) == 0) or (len(newpass2) == 0): html = '输入信息错误' else: user_info_list = open(passfile, 'rb').readlines() tmp_file = open('%s.tmp' % passfile, 'wb') # 如果是用户配置则查看是否为用户,如果不是直接写入临时文件 for li in xrange(len(user_info_list)): if user_info_list[li].find('=') > 0 : u = strip(user_info_list[li].split('=')[0]) p = strip(user_info_list[li].split('=')[1]) #e = strip(user_info_list[li+1].split('#')[1]) if (u == user) and (p == oldpass): tmp_file.write('%s=%s\n' % (u, newpass1)) # tmp_file.write('#%s\n' % (e)) reboot_status = 1 # li = li+1 else: tmp_file.write(user_info_list[li]) else: tmp_file.write(user_info_list[li]) if reboot_status == 1: import os import shutil shutil.move('%s.tmp' % passfile, passfile) os.system("killall svnserve && %s" % svn_start_comm) html = '处理完成请重试' self.write(html) class SendUserInfoHandler(tornado.web.RequestHandler): def get(self): email = self.get_argument('email') user_info_list = open(passfile, 'rb').readlines() # 循环读取每一行 html = '没有找到相关信息' for li in xrange(len(user_info_list)): context = user_info_list[li][:-1] # 如果有用户配置的则分解 if context.find('=') > 0 : u = strip(user_info_list[li].split('=')[0]) p = strip(user_info_list[li].split('=')[1]) e = strip(user_info_list[li+1].split('#')[1]) # 如果用户邮箱与输入邮箱相同则发邮件 if e == strip(email): mail_send("user:%s. passwd:%s" % (u, p), email) html = '邮件发送注意查收' self.write(html) application = tornado.web.Application([ (r"/", MainHandler), (r"/editpass/", EditPassHandler), (r"/senduserinfo/", SendUserInfoHandler), ]) if __name__ == "__main__": application.listen(webport) tornado.ioloop.IOLoop.instance().start()

源码包websvn

1月 27

Raspberry pi 软件模拟PWM

  Raspberry pi 只有一个PWM。看到国外高手有人用软件模拟PWM。我也测试一下。以下部分只是测试记录,文档和代码均来自官方网站。

使用root用户安装softpwm,这个安装记录直接拷贝到系统里运行成功就行。
apt-get -y update
apt-get -y upgrade
apt-get install -y devscripts build-essential fakeroot dh-make mercurial dh-make
apt-get install -y devscripts build-essential fakeroot
mkdir temp
cd temp
hg clone http://hg.code.sf.net/p/raspberry-gpio-python/code raspberry-gpio-python -r 0.5.4
cd raspberry-gpio-python
python setup.py sdist
cd dist/
tar xvfz RPi.GPIO-0.5.4.tar.gz
mv RPi.GPIO-0.5.4 rpi.gpio-0.5.4
cd rpi.gpio-0.5.4
dh_make -s -f ../RPi.GPIO-0.5.4.tar.gz
rm -rf debian
cp -a ../../debian/ ./
debuild -us -uc
debuild clean
python setup.py install

测试代码如下,使用LED小灯测试:

#!/bin/env python
# -*-coding:utf-8 -*-
import time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(7, GPIO.OUT)

p = GPIO.PWM(7, 50)  #frequency=100Hz
p.start(0)
try:
    while 1:
        for dc in range(0, 101, 5):
            p.ChangeDutyCycle(dc)
            time.sleep(0.1)
        for dc in range(100, -1, -5):
            p.ChangeDutyCycle(dc)
            time.sleep(0.1)
except KeyboardInterrupt:
    pass
p.stop()
GPIO.cleanup()

来源
http://sourceforge.net/p/raspberry-gpio-python/wiki/PWM/

1月 03

测试python计算MD5和CRC的速度

  大量数据想均匀分布到不同的数据库存储,当前方法将key进行MD5或CRC计算,取最后一位分别对应到相应的存储位置。测文本17721088行。
两个脚本如下:
MD5部分

import hashlib
import time

file_list = open('di.txt')
start =time.time()
for get_str in file_list:
    if get_str[-1] == '\n':
        get_str = get_str[:-1]
    get_crc = hashlib.md5(get_str).hexdigest()
    #print get_crc
end = time.time()
print end-start

CRC部分

import zlib
import time

file_list = open('di.txt')
start =time.time()
for get_str in file_list:
    if get_str[-1] == '\n':
        get_str = get_str[:-1]
    get_crc = zlib.crc32(get_str) & 0xffffffff
end = time.time()
print end-start

md5计算用58.81秒,crc计算用27.06秒。CRC速度比md5快一倍。但是MD5是16进制,CRC是十进制。如果要将CRC转为16进制,所用时间和MD5用时相似。

12月 20

linux上用python产生的文件名到window下乱码解决

  linux使用utf-8,用python产生了一批文件,下载到windows上文件名字乱码,内容没有问题。这是由于windows使用GBK,但是能支持utf-8,所以文件名乱码,内容正常。
  解决方法就是把产生的文件在用“GBK”编码重拷贝一次。举例如下:

import os
_name = u"hello"
file_name = "%s.txt" % (get_project)
os.system("mv %s %s" % (file_name, file_name.encode("GBK")))

需要注意:如果文件名字是纯英文或者数字,系统会认为mv是同一个文件,可能会丢失,所以要判断一下。