ferragamo shoes timberland outlet tory burch north face coats Timberland Sale paul smith bags Paul Smith handbag dsquared sale tods UK
So Tired!_! - for our good life, must to do something. let's do it!

2012年01月20日

[转]如何做一个可以执行的年度计划?附工具下载

by Nick Xu — Categories: 其它Leave a comment

转眼间一年又过去了,2011年过的怎么样?愿望都实现了吗?2012年有什么打算呢?

这一次木立方俱乐部的活动主题是“如何做一个可执行的年度计划~”吸引到了25位朋友参加。

在活动的一开始,我们几个拿出去年制作的年度计划,给大家汇报了完成情况,比较有意思的是,基本上都是完成了80%左右~

看来大家的2011过的都蛮成功的(看看脸上的笑容就知道了!)。

对于2012年的计划,我们为大家提供了一套流程和工具,大家用了之后都说蛮不错的(提前一周就发给大家了)。

所以我也在博客上跟大家分享,这样一来,以后就不需要花太多的心思在方法和工具上,专注在自己深思考就好。

第一步:问正确的问题

年计划工具A

首先,大家可以用A4纸打印出上面的这个“年度计划小人儿”,他将帮助我们思考自己的规划。

图上面有8个问题,分别是:

  1. 你的个人核心价值观是什么?
  2. 个人发展所需要克服的矛盾:挡住你去路的大石头是什么?比如没有养成的某种习惯、一直没有克服的障碍
  3. 未来五年远景(有些人是三年):你想要你五年后是一个什么样子?
  4. 未来两年目标:你对未来两年有什么想法?
  5. 2012个人主题:未来的一年都要完成哪些任务?
  6. 2012个人行动计划:具体的行动、周期、时间点
  7. 需要放弃的资源:精力是有限的,你愿意为了你的目标而主动放弃什么?
  8. 2012年主题词:用一个词概括你的2012

这个年度计划小人来自于图像引导师臧贤凯,所以你会发现这几个问题和图像中的身体有奇妙的联系:

  1. 个人价值观—是我们脑袋里一直存在的东西,只不过我们要把它描述出来
  2. 需要克服的矛盾—这些矛盾来自于我们的内心,而也只有我们内心的力量才能战胜它。
  3. 五年、两年目标—我们的双手必须牢牢抓住的东西
  4. 个人任务和行动计划—这需要我们迈开双脚去行动
  5. 需要放弃的资源—是我们背后的阴影,我们要向着有光的地方走去,就势必在身后留下长长的背影。
  6. 主题词—红旗!必须夺下来的红旗

U58847903 130c79ac7e6g213

我回答这8个问题用了几周的时间,问对了问题就会引发很多的思考,年计划真的不像想象的那么简单,不花一些精力去深思考,是没有办法完成的。

大家试试看吧!

第二步:梳理出行动

我们设计了一个Excel模板,方便大家使用。

特别值得一提的是,我们在里面加入了“预算”

比如说你想要学习沟通,想要报一个卡内基的课程,那么你需要多少预算?

如果你想要参加Toastmaster俱乐部,那么你需要多少会费?

你每月需要花在社交上的费用大概是多少?

如果你已经把任务分解到行动了的话,你就能从这张表格里得到全年的费用预算,一目了然

工具可以协助行动,工具还可以触发思考,你能把全年的行动规划下来吗?试试看?!

屏幕快照 2012 01 14 下午02 55 25

第三步:规划到月历

我会给计划制定时间节点,比如说:

  • 大概几月做研习会
  • 几月去参加课程
  • 项目这个月应该是什么进度

然后我会把他写在月历上,新的一月开始,这一个月的重点是什么,就心里清楚了。

我们除了在活动现场送给大家可以摆在桌上的月历之外,还提供一个电子版下载,可以打印出来使用,很方便咯。

屏幕快照 2012 01 14 下午03 02 40

第四步:和伙伴们分享

我们这次来参加活动的所有人都约定好:6月份和12月份的时候,我们还要聚在一起,分享年计划的执行情况,想起来就让人兴奋。

我以前对“分享”这个词不是很重视,当我开始在新浪微博发起“每月培养一个好习惯”的活动后,体会到了“分享”的可怕之处,互相的鼓励和打气能形成一个正向能量圈,很快乐的坚持下去。

所以,不管你的年计划是什么,希望你能和身边的朋友们分享,看看会发生什么。

结语:

制作年度计划四步法和工具下载:

第一步:思考并填写“年度计划小人儿” 年度计划小人儿.jpg

第二步:把“年度计划小人儿”里的“2012个人主题”拿出来,在表格里孵化出行动 2012个人成长实施计划(工具二).xlsx

第三步:把有时间节点的或者周期性的行动,写在月历上 2012成长工具年历中文版.xls

第四步:希望大家把这些工具还有你的计划和朋友们一起分享。

2012年01月17日

三种web性能压力测试工具http_load webbench ab Siege

by Nick Xu — Categories: LinuxLeave a comment

http_load

下载地址:http://www.acme.com/software/http_load/http_load-12mar2006.tar.gz

http_load以并行复用的方式运行,用以测试web服务器的吞吐量与负载。但是它不同于大多数压力测试工具,它可以以一个单一的进程运行,一般不会把客户机搞死。可以可以测试HTTPS类的网站请求。

命令格式:http_load  -p 并发访问进程数  -s 访问时间  需要访问的URL文件
参数介绍

        -p 并发访问进程数

        -f 总的访问次数

        -r 每秒的访问频率

        -s 总的访问时间

通常参数组合:-p –f;-r -s

引用
http_load -p 30 -s 60  urllist.txt准备URL文件:tst.list,文件格式是每行一个URL,URL最好超过50-100个测试效果比较好,另外,测试结果中主要的指标是 fetches/sec 这个选项,即服务器每秒能够响应的查询次数,用这个指标来衡量性能

 

引用
% ./http_load -rate 10 -seconds 60 urllist.txt
49 fetches, 4 max parallel, 289884 bytes, in 10.0148 seconds
5916 mean bytes/connection
4.89274 fetches/sec, 28945.5 bytes/sec
msecs/connect: 28.8932 mean, 44.243 max, 24.488 min
msecs/first-response: 63.5362 mean, 81.624 max, 57.803 min

4.89274 fetches/sec 这个值得就是说服务器每秒能够响应的查询次数为4.8左右
这个值得是根据 49 fetches / 10.0148 seconds 秒计算出来的


webbench
webbench是Linux下的一个网站压力测试工具,最多可以模拟3万个并发连接去测试网站的负载能力。
下载地址:

http://cid-9601b7b7f2063d42.skydrive.live.com/self.aspx/Public/webbench-1.5.tar.gz

安装
#tar zxvf webbench-1.5.tar.gz
#cd webbench-1.5
#make && make install
会在当前目录生成webbench可执行文件,直接可以使用了

用法:
webbench -c 并发数 -t 运行测试时间 URL
如:webbench -c 5000 -t 120 http://www.askwan.com


ab 

ab是Apache服务器自己带的性能测试工具,用它可以对指定的URL进行模拟访问,然后生成一份有关访问效率的报表,从中可以大概看出网站在高压力情况下的表现。

Windows下的ab.exe一般都在Apache安装目录的bin目录下。这里举几个我实际中用过的例子:

对http://localhost/dz7/index.php产生400次请求
ab -n 400 http://localhost/dz7/index.php
测试完成后,ab会输出测试的结果:

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Finished 400 requests

Server Software:        Apache/2.2.11
Server Hostname:        localhost
Server Port:            80

Document Path:          /dz7/index.php
Document Length:        7015 bytes

Concurrency Level:      1
Time taken for tests:   21.623 seconds
Complete requests:      400
Failed requests:        399
   (Connect: 0, Receive: 0, Length: 399, Exceptions: 0)
Write errors:           0
Total transferred:      2968811 bytes
HTML transferred:       2805205 bytes
Requests per second:    18.50 [#/sec] (mean)
Time per request:       54.057 [ms] (mean)
Time per request:       54.057 [ms] (mean, across all concurrent requests)
Transfer rate:          134.08 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   1.3      0      16
Processing:    31   54  64.5     47    1265
Waiting:       16   51  64.3     47    1250
Total:         31   54  64.5     47    1265

Percentage of the requests served within a certain time (ms)
  50%     47
  66%     47
  75%     47
  80%     47
  90%     47
  95%     62
  98%    141
  99%    187
 100%   1265 (longest request)

参数-n设定请求的次数;另外,还可以用-c来设定并发访问数,例如要模拟50个并发访问,可以用
ab -n 400 -c 50 http://localhost/dz7/index.php

此外,还有一个实际的问题,就是如何用ab来模拟已登录的用户的访问。绝大部分程序的登录机制都是用Cookie+Session来实现的,浏览器在每次请求时都发送一个Cookie,里面记录了Session的SID。你可以先在利用Firefox的Firebug插件来确定Cookie里的内容是什么。
firebug_cookie
从中可以看到表示登录用户的内容是“QfI_sid=55ySsk”。ab可以用-C(大写的C)来设定每次请求用发送的Cookie。所以
ab -n 400 -c 50 -C "QfI_sid=55ySsk" http://localhost/dz7/index.php
就可以模拟已登录用户的400次访问,并发数为50的情况。

最后再透露一个绝技:
ab --help

 

四、Siege
一款开源的压力测试工具,可以根据配置对一个WEB站点进行多用户的并发访问,记录每个用户所有请求过程的相应时间,并在一定数量的并发访问下重复进行。
官方:http://www.joedog.org/
Siege下载:http://soft.vpser.net/test/siege/siege-2.67.tar.gz
解压:
# tar -zxf siege-2.67.tar.gz
进入解压目录:
# cd siege-2.67/
安装:
#./configure ; make
#make install

使用
siege -c 200 -r 10 -f example.url
-c是并发量,-r是重复次数。 url文件就是一个文本,每行都是一个url,它会从里面随机访问的。

example.url内容:

http://www.licess.cn
http://www.vpser.net
http://soft.vpser.net

结果说明
Lifting the server siege… done.
Transactions: 3419263 hits //完成419263次处理
Availability: 100.00 % //100.00 % 成功率
Elapsed time: 5999.69 secs //总共用时
Data transferred: 84273.91 MB //共数据传输84273.91 MB
Response time: 0.37 secs //相应用时1.65秒:显示网络连接的速度
Transaction rate: 569.91 trans/sec //均每秒完成 569.91 次处理:表示服务器后
Throughput: 14.05 MB/sec //平均每秒传送数据
Concurrency: 213.42 //实际最高并发数
Successful transactions: 2564081 //成功处理次数
Failed transactions: 11 //失败处理次数
Longest transaction: 29.04 //每次传输所花最长时间
Shortest transaction: 0.00 //每次传输所花最短时间

2012年01月11日

nginx做非80端口转发

by Nick Xu — Categories: LinuxLeave a comment

nginx可以很方便的配置成反向代理服务器
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://147.16.24.175:9500;
proxy_set_header Host $host:80;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Via “nginx”;
}
}
但是如果nginx的监听端口不是默认的80端口,改为其他端口如81端口。
后端服务器中request.getServerPort()无法获得正确的端口,返回的仍然是80;
在response.sendRedirect()时,客户端可能无法获得正确的重定向url。
正确的配置方法为
在 $host之后加上端口号,如$host:81
server {
listen       83;
server_name  localhost;
location / {
proxy_pass  http://147.16.24.175:9500;
proxy_set_header   Host             $host:83;
proxy_set_header   X-Real-IP        $remote_addr;
proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
proxy_set_header Via    “nginx”;
}
}

2011年12月29日

用geohash字符串实现附近地点搜索

by Nick Xu — Categories: PythonLeave a comment

可以考虑使用geohash算法。

http://code.google.com/p/python-geohash/

geohash是一种地址编码,它能把二维的经纬度编码成一维的字符串。比如,北海公园的编码是wx4g0ec1。

geohash-intro-01.png

geohash有以下几个特点:

首先,geohash用一个字符串表示经度和纬度两个坐标。某些情况下无法在两列上同时应用索引 (例如MySQL 4之前的版本,Google App Engine的数据层等),利用geohash,只需在一列上应用索引即可。

其次,geohash表示的并不是一个点,而是一个矩形区域。比如编码wx4g0ec19,它表示的是一个矩形区域。 使用者可以发布地址编码,既能表明自己位于北海公园附近,又不至于暴露自己的精确坐标,有助于隐私保护。

第三,编码的前缀可以表示更大的区域。例如wx4g0ec1,它的前缀wx4g0e表示包含编码wx4g0ec1在内的更大范围。 这个特性可以用于附近地点搜索。首先根据用户当前坐标计算geohash(例如wx4g0ec1)然后取其前缀进行查询 (SELECT * FROM place WHERE geohash LIKE ‘wx4g0e%’),即可查询附近的所有地点。

geohash-intro-02.png

geohash的算法

下面以(39.92324, 116.3906)为例,介绍一下geohash的编码算法。首先将纬度范围(-90, 90)平分成两个区间(-90, 0)、(0, 90), 如果目标纬度位于前一个区间,则编码为0,否则编码为1。由于39.92324属于(0, 90),所以取编码为1。然后再将(0, 90)分成 (0, 45), (45, 90)两个区间,而39.92324位于(0, 45),所以编码为0。以此类推,直到精度符合要求为止,得到纬度编码为1011 1000 1100 0111 1001。

纬度范围 划分区间0 划分区间1 39.92324所属区间
(-90, 90) (-90, 0.0) (0.0, 90) 1
(0.0, 90) (0.0, 45.0) (45.0, 90) 0
(0.0, 45.0) (0.0, 22.5) (22.5, 45.0) 1
(22.5, 45.0) (22.5, 33.75) (33.75, 45.0) 1
(33.75, 45.0) (33.75, 39.375) (39.375, 45.0) 1
(39.375, 45.0) (39.375, 42.1875) (42.1875, 45.0) 0
(39.375, 42.1875) (39.375, 40.7812) (40.7812, 42.1875) 0
(39.375, 40.7812) (39.375, 40.0781) (40.0781, 40.7812) 0
(39.375, 40.0781) (39.375, 39.7265) (39.7265, 40.0781) 1
(39.7265, 40.0781) (39.7265, 39.9023) (39.9023, 40.0781) 1
(39.9023, 40.0781) (39.9023, 39.9902) (39.9902, 40.0781) 0
(39.9023, 39.9902) (39.9023, 39.9462) (39.9462, 39.9902) 0
(39.9023, 39.9462) (39.9023, 39.9243) (39.9243, 39.9462) 0
(39.9023, 39.9243) (39.9023, 39.9133) (39.9133, 39.9243) 1
(39.9133, 39.9243) (39.9133, 39.9188) (39.9188, 39.9243) 1
(39.9188, 39.9243) (39.9188, 39.9215) (39.9215, 39.9243) 1

经度也用同样的算法,对(-180, 180)依次细分,得到116.3906的编码为1101 0010 1100 0100 0100。

经度范围 划分区间0 划分区间1 116.3906所属区间
(-180, 180) (-180, 0.0) (0.0, 180) 1
(0.0, 180) (0.0, 90.0) (90.0, 180) 1
(90.0, 180) (90.0, 135.0) (135.0, 180) 0
(90.0, 135.0) (90.0, 112.5) (112.5, 135.0) 1
(112.5, 135.0) (112.5, 123.75) (123.75, 135.0) 0
(112.5, 123.75) (112.5, 118.125) (118.125, 123.75) 0
(112.5, 118.125) (112.5, 115.312) (115.312, 118.125) 1
(115.312, 118.125) (115.312, 116.718) (116.718, 118.125) 0
(115.312, 116.718) (115.312, 116.015) (116.015, 116.718) 1
(116.015, 116.718) (116.015, 116.367) (116.367, 116.718) 1
(116.367, 116.718) (116.367, 116.542) (116.542, 116.718) 0
(116.367, 116.542) (116.367, 116.455) (116.455, 116.542) 0
(116.367, 116.455) (116.367, 116.411) (116.411, 116.455) 0
(116.367, 116.411) (116.367, 116.389) (116.389, 116.411) 1
(116.389, 116.411) (116.389, 116.400) (116.400, 116.411) 0
(116.389, 116.400) (116.389, 116.394) (116.394, 116.400) 0

接下来将经度和纬度的编码合并,奇数位是纬度,偶数位是经度,得到编码 11100 11101 00100 01111 00000 01101 01011 00001。

最后,用0-9、b-z(去掉a, i, l, o)这32个字母进行base32编码,得到(39.92324, 116.3906)的编码为wx4g0ec1。

十进制 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
base32 0 1 2 3 4 5 6 7 8 9 b c d e f g
十进制 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
base32 h j k m n p q r s t u v w x y z

解码算法与编码算法相反,先进行base32解码,然后分离出经纬度,最后根据二进制编码对经纬度范围进行细分即可,这里不再赘述。 不过由于geohash表示的是区间,编码越长越精确,但不可能解码出完全一致的地址。

geohash的应用:附近地址搜索

geohash的最大用途就是附近地址搜索了。不过,从geohash的编码算法中可以看出它的一个缺点:位于格子边界两侧的两点, 虽然十分接近,但编码会完全不同。实际应用中,可以同时搜索当前格子周围的8个格子,即可解决这个问题。

以geohash的python库为例,相关的geohash操作如下:

>>> import geohash
>>> geohash.encode(39.92324, 116.3906, 5)  # 编码,5表示编码长度
'wx4g0'
>>> geohash.expand('wx4g0')                # 求wx4g0格子及周围8个格子的编码
['wx4ep', 'wx4g1', 'wx4er', 'wx4g2', 'wx4g3', 'wx4dz', 'wx4fb', 'wx4fc', 'wx4g0']

最后,我们来看看本文开头提出的两个问题:速度慢,缓存命中率低。使用geohash查询附近地点,用的是字符串前缀匹配:

SELECT * FROM place WHERE geohash LIKE 'wx4g0%';

而前缀匹配可以利用geohash列上的索引,因此查询速度不会太慢。另外,即使用户坐标发生微小的变化, 也能编码成相同的geohash,这就保证了每次执行相同的SQL语句,使得缓存命中率大大提高。

2011年12月28日

用Windows的远程桌面连接访问Debian和Ubuntu图形界面

by Nick Xu — Categories: LinuxLeave a comment
Linux的服务器我一般是不安装图形界面的,但是有的客户需要使用VPS的图形界面,又觉得Windows的VPS性价比不高,所以我就尝试了在Windows上远程访问Debian和Ubuntu。

要实现这一功能非常简单,在Windows客户端无需任何设置,直接使用系统附件里的“远程桌面连接”即可。而在服务端,也只需要安装几个软件并做小小的设置即可。

一、服务端的安装与设置:

1.安装Tightvncserver和xrdp这两个软件包

  1. # apt-get install tightvncserver xrdp

复制代码

2.关闭Gnome Terminal的plugin以解决键盘映射错误的问题:
Application-system tools-editor
选择apps–>gnome_settings_daemon–>plugins–>keyboard–>取消勾选active

3.在终端运行vpcserver命令,输入密码后会生成相关配置文件:

  1. # vncserver

复制代码

二、Windows客户端的使用:

点击“开始”菜单-“所有程序”-“附件”-“远程桌面连接”,在“计算机”一栏里输入你VPS的IP地址,然后点击“连接”,在接下来的对话框里输入用户名和密码,点击“OK”之后即可进入Linux VPS的桌面。

想要退出的话只要选择注销(log out)即可。

未解决的问题:
Debian服务器的locale是中文,但是远程访问的界面却变成了英文,无法调出中文输入法,不过除终端外的中文显示正常;

2011年12月13日

在终端上,python打印出不同颜色的文字

by Nick Xu — Categories: Linux, PythonLeave a comment

终端的字符颜色是用转义序列控制的,是文本模式下的系统显示功能,和具体的语言无 关。

转义序列是以 ESC 开头,可以用 \033 完成相同的工作(ESC 的 ASCII 码用十进制表 示就是 27, = 用八进制表示的 33)。

\033[显示方式;前景色;背景色m

显示方式:0(默认值)、1(高亮)、22(非粗体)、4(下划线)、24(非下划线)、 5(闪烁)、25(非闪烁)、7(反显)、27(非反显)

前景色:30(黑色)、31(红色)、32(绿色)、 33(黄色)、34(蓝色)、35(洋 红)、36(青色)、37(白色)

背景色:40(黑色)、41(红色)、42(绿色)、 43(黄色)、44(蓝色)、45(洋 红)、46(青色)、47(白色)

\033[0m 默认

\033[1;32;40m 绿色

033[1;31;40m 红色

print “\033[1;31;40m%s\033[0m” % ” 输出红色字符”

2011年12月12日

mysql经纬度坐标距离计算

by Nick Xu — Categories: 其它Leave a comment

本文章主要解决数据库如果存有经纬度,获取一定距离的记录数

首先我们在mysql建立一个可重复使用的计算两个坐标经纬度的Function



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
DELIMITER $
DROP FUNCTION IF EXISTS `GetDistance`$
 
CREATE FUNCTION `GetDistance`(lat1 FLOAT,lng1 FLOAT, lat2 FLOAT,lng2 FLOAT)
RETURNS  DOUBLE
BEGIN
    DECLARE  distance  DOUBLE;
    if ((lat1=0 and lng1=0) or (lat2=0 and lng2=0)) then    
        set distance=99999999.00;
    else
    SET distance= 2 * 6378.137* ASIN(SQRT(POW(SIN(PI() * (lat1-lat2) / 360), 2)+COS(PI() * lat1 / 180)* COS(lat2* PI() / 180) * POW(SIN(PI() * (lng1-lng2) / 360), 2)));
    end if;
 
    RETURN distance;
END$
DELIMITER ;


接下来,就是运用这个function计算距离了。
为了提高效率,在计算距离时首先通过经度和纬度过滤,然后再通过距离过滤,因为如果计算所有记录的距离毕竟不是很高效的做法。

2011年12月8日

使用 SQLObject 连接数据库与 Python

by Nick Xu — Categories: PythonLeave a comment

通过提供用于操作数据库表的类和对象,对象关系映射工具有助于提高生产率。Python 最好的对象关系映射工具是 SQLObject —— 一个开放源码项目,它几乎完成编程数据库所需的所有操作。sqlobject支持数据库类型有sqlite3,mysql,PostgreSQL等等

1、安装和设置 SQLObject
SQLObject 具有一个 setup.py 文件,安装方式与其他任何 Python 包一样。直接python setup.py即可,当然你也可以进一步使用setup tools即可:easyinstall.exe sqlobject即可,呵呵,十分简单方便哦。

2、数据库准备(本文使用mysql为例)
要实际使用 SQLObject,需要设置数据库包以及这种数据库的 Python 接口。SQLObject 连接多种数据库,其中包括三个大的开放源码产品:MySQL、PostgreSQL 和无服务器 SQLite。
——————————-
mysql> use mysql;
Database changed
mysql> create database sqlobject_demo;
Query OK, 1 row affected (0.00 sec)
mysql> grant all privileges on sqlobject_demo to ‘dbuser’@’localhost’
identified by ‘dbpassword’;
Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
——————————-

3、连接数据库
如果想让应用程序使用 SQLite 数据库,则需要将数据库文件的路径写入位于sqlobject.sqlite 包的 SQLite 连接构建器中。如果数据库文件不存在,QLObject 将告诉 SQLite 创建一个,代码如下:
——————————-
import sqlobject
from sqlobject.sqlite import builder
conn = builder()(‘sqlobject_demo.db’)
——————————-
如果使用的是 MySQL 或带有服务器的其他数据库,则将数据库连接信息传递到连接构建器中。上面提供了在上一节创建的 MySQL 数据库的示例。
——————————-
import sqlobject
from sqlobject.mysql import builder
conn = builder()(user=’dbuser’, passwd=’dbpassword’,
host=’localhost’, db=’sqlobject_demo’)
——————————-
不管连接哪种数据库,连接代码都应该放置在一个名称类似 Connection.py 的文件中,且该文件存储在一些通常可访问的位置中。这样,可以导入您定义的所有类,并使用已经构建的conn 对象。conn 变量将包含所有与数据库相关的详细信息。
注意:SQLObject 的一些特性不可用于 SQLite 或 MySQL。

4、定义模式
SQLObject 使得操作数据库表变得容易。看第一个简单的例子,考虑一个电话簿应用程序的由单个表组成的数据库模式,如下所示。
字段    类型    说明
id        Int        主键
number    String    “(###) ###-####”字符串格式;应该惟一
owner    String    这是谁的号码?
last_call    Date    用户最后一次呼叫该号码是什么时候?

该表的 SQL 类似如下:
CREATE TABLE phone_number (
id INT PRIMARY KEY AUTO_INCREMENT,
number VARCHAR(14) UNIQUE,
owner VARCHAR(255),
last_call DATETIME,
notes TEXT
)
使用 SQLObject,不需要编写该 SQL 代码。通过定义 Python 类来定义该数据表。该代码将进入名为 PhoneNumber.py 的文件中。
——————————-
import sqlobject
from Connection import conn

class PhoneNumber(sqlobject.SQLObject):
_connection = conn
number = sqlobject.StringCol(length=14, unique=True)
owner = sqlobject.StringCol(length=255)
lastCall = sqlobject.DateTimeCol(default=None)
PhoneNumber.createTable(ifNotExists=True)
——————————-

定义表的类还有一组定义表字段的成员。SQLObject 提供了 StringCol、BoolCol 等等 —— 一个类对应一种数据库字段类型。
createTable() 方法第一次运行时,SQLObject 将创建一个名为 phone_number 的表。然后,它将只使用该表,因为您将 ifNotExists 设置为 True 来调用该方法。

最后注意,无需在 PhoneNumber 中为 id 字段创建字段对象。因为 SQLObject 总是需要该字段对象,所以它总会创建一个。

5、处理CRUD
著名的缩写词 CRUD 代表对数据库行进行的四种操作:Create、Read、Update 和 Delete。定义了与数据库表对应的类之后,SQLObject 将对表行的操作表示为对类及其实例的操作。

创建
要创建数据库行,需创建对应类的实例,代码如下:
——————————-
>>> from PhoneNumber import PhoneNumber
>>> myPhone = PhoneNumber(number=’(415) 555-1212′,
owner=’Leonard Richardson’)
——————————-
现在 phone_number 表有一个存储我的姓名的行。PhoneNumber 构造函数将表列的值作为关键字参数。它使用您提供的数据创建一行 phone_number。如果由于某种原因,数据不能进入数据库,则构造函数抛出一个异常。当电话号码无效时,会发生如下情况:
——————————-
>>> badPhone = PhoneNumber()
Traceback (most recent call last):
File “<stdin>”, line 1, in ?

TypeError: PhoneNumber() did not get expected keyword argument number
如果电话号码已经在数据库中,将会看到:
——————————-
>>> duplicatePhone = PhoneNumber(number=”(415) 555-1212″)
Traceback (most recent call last):
File “<stdin>”, line 1, in ?

TypeError: PhoneNumber() did not get expected keyword argument owner

读取(和查询)
SQLObject 类的实例的所有字段可用作成员。这与其他一些将数据库行当作字典的数据库映射工具相反。因此,对于数据库行中的每个字段,PhoneNumber 对象都具有一个成员。
——————————-
>>> myPhone.id
1
>>> myPhone.owner
‘Leonard Richardson’
>>> myPhone.number
‘(415) 555-1212′
>>> myPhone.lastCall == None
True
但如何检索数据库中已经存在的 PhoneNumber 对象呢?需要对数据库执行查询来获取。这就是 SQLObject 的查询构造工具包(该软件包最有趣的特性之一)发挥作用的地方。它允许将 SQL 查询表示为 Python 对象链。如果您熟悉 Java™ 编程语言的对象关系包的话,它与可以对 Torque 中 Criteria 对象执行的操作一样。
您定义的每个 SQLObject 类都有一个 select() 方法。该方法接受一个定义查询的对象,返回与该查询匹配的项列表。例如,下面这个方法调用返回包含数据库中第一个电话号码的列表:
——————————-
>>> PhoneNumber.select(PhoneNumber.q.id==1)
<sqlobject.main.SelectResults object at 0xb7b76cac>
>>> PhoneNumber.select(PhoneNumber.q.id==1)[0]
<PhoneNumber 1 number=’(415) 555-1212′ lastCall=None
owner=’Leonard Richardson’>
——————————-
PhoneNumber.q.id 指明想要对 phone_number 表的 id 字段运行查询。SQLObject 过载比较操作符(==、!=、<、>= 等等)来执行除布尔表达式之外的查询。表达式PhoneNumber.q.id==1 是与 id 字段值为 1 的每行相匹配的查询。
——————————-
>>> PhoneNumber.select(PhoneNumber.q.id < 100)[0]
<PhoneNumber 1 number=’(415) 555-1212′ lastCall=None
owner=’Leonard Richardson’>
>>> PhoneNumber.select(PhoneNumber.q.owner==’Leonard Richardson’).count()
1
>>> PhoneNumber.select(PhoneNumber.q.number.startswith(‘(415)’)).count()
1
——————————-
可以使用 SQLObject 的 AND 和 OR 函数来组合查询子句:
——————————-
>>> from sqlobject import AND, OR
>>> PhoneNumber.select(AND(PhoneNumber.q.number.startswith(‘(415)’),
>>>                        PhoneNumber.q.lastCall==None)).count()
1
——————————-
下列查询获取一年中呼叫过的所有人以及从未呼叫过的所有人:
——————————-
>>> import datetime
>>> oneYearAgo = datetime.datetime.now() – datetime.timedelta(days=365)
>>> PhoneNumber.select(OR(PhoneNumber.q.lastCall==None,
…                       PhoneNumber.q.lastCall < oneYearAgo)).count()
1
——————————-

更新
如果更改 PhoneNumber 对象的一个成员,则该更改被自动镜像映射至数据库:
——————————-
>>> print myPhone.owner
Leonard Richardson
>>> print myPhone.lastCall
None
>>> myPhone.owner = “Someone else”
>>> myPhone.lastCall = datetime.datetime.now()
>>> #Fetch the object fresh from the database.
>>> newPhone = PhoneNumber.select(PhoneNumber.q.id==1)[0]
>>> print newPhone.owner
Someone else
>>> print newPhone.lastCall
2005-05-22 21:20:24.630120

注意:SQLObject 不允许更改对象的主键。通常最好是让 SQLObject 来管理表的 id 字段,即使是您不使用 SQLObject 时碰巧用另一个字段作为主键。

删除

删除特定行对象的方法是将其 ID 传递到其类的 delete() 方法中:
——————————-
>>> query = PhoneNumber.q.id==1
>>> print “Before:”, PhoneNumber.select(query).count()
Before: 1
>>> PhoneNumber.delete(myPhone.id)
>>> print “After:”, PhoneNumber.select(query).count()
After: 0
——————————-

6、验证和转换数据
SQLObject 通过允许定义验证和转换入站数据的钩子方法来解决这个问题。可以为表中的每个字段定义一个方法。字段的钩子方法命名为 _set_[field name](),不管是作为 create 操作还是 update 操作的一部分,每当要为该字段设置一个值时,都会调用该方法。钩子方法应(可选)将入站值转换为可接受格式,然后设置该值。否则,它应抛出异常。要实际设置一个值,该方法需要调用 SQLObject 方法 _SO_set_(field name)。
【PhoneNumber 的 _set_number() 方法。如果电话号码完全没有格式化,比如 4155551212,则该方法将该数字格式化为 (415) 555-1212。否则,如果数字格式不正确,该方法会抛出 ValueError。正确格式化的电话号码 —— 或者是转换为正确格式的电话号码 —— 被正确传递给 SQLObject 的 _SO_set_number() 方法。】
——————————-
import re
def _set_number(self, value):
if not re.match(‘\([0-9]{3}\) [0-9]{3}-[0-9]{4}’, value):
#It’s not in the format we expect.
if re.match(‘[0-9]{10}’, value):
#It’s totally unformatted; add the formatting.
value = “(%s) %s-%s” % (value[:3], value[3:6], value[6:])
else:
raise ValueError, ‘Not a phone number: %s’ % value
self._SO_set_number(value)
——————————-

7、定义表之间的关系
真正的数据库应用程序通常具有多个相关表,SQLObject 允许将表之间的关系定义为外键。作为演示,我们将一个小的数据库规范化(normalization)应用于上一示例,将 PhoneNumber 的 owner 字段分割到单独的 person 表中。清单 14 所示的代码保存在名为 PhoneNumberII.py 的文件中。
——————————-
import sqlobject
from Connection import conn
class PhoneNumber(sqlobject.SQLObject):
_connection = conn
number = sqlobject.StringCol(length=14, unique=True)
owner = sqlobject.ForeignKey(‘Person’)
lastCall = sqlobject.DateTimeCol(default=None)

class Person(sqlobject.SQLObject):
_idName=’fooID’
_connection = conn
name = sqlobject.StringCol(length=255)
#The SQLObject-defined name for the “owner” field of PhoneNumber
#is “owner_id” since it’s a reference to another table’s primary
#key.
numbers = sqlobject.MultipleJoin(‘PhoneNumber’, joinColumn=’owner_id’)

Person.createTable(ifNotExists=True)
PhoneNumber.createTable(ifNotExists=True)
——————————-

该 PhoneNumber 类具有与旧类相同的成员,但它的 owner 成员是对 person 表的主键的引用,而不是对 phone_number 表中字符串列的引用。这使得表示具有两个电话号码的个人成为可能:
——————————-
>>> from PhoneNumberII import PhoneNumber, Person
>>> me = Person(name=’Leonard Richardson’)
>>> work = PhoneNumber(number=”(650) 555-1212″, owner=me)
>>> cell = PhoneNumber(number=”(415) 555-1212″, owner=me)
——————————-

Person 的 numbers 成员,一个 SQLObject MultipleJoin,使得基于 person 到 phone_number 的连接进行查询变得容易:
——————————-
>>> for phone in me.phoneNumbers:
…     print phone.number

(650) 555-1212
(415) 555-1212
——————————-

同样,SQLObject 允许使用 MultipleJoin 类进行多对多连接的查询。

8、将 SQLObject 用于现有表
SQLObject 的一个常见用途是为另一个应用程序创建的数据库提供 Python 接口。SQLObject 有多个特性可用于实现这一点。

数据库内省
如果正在使用数据库中已经存在的表,则不需要在 Python 中定义列。SQLObject 可以通过数据库内省来提取它需要的信息。例如,清单 17 中的代码保存在 PhoneNumberIII.py 中。
——————————-
import sqlobject
from Connection import conn
class PhoneNumber(sqlobject.SQLObject):
_connection = conn
_fromDatabase = True
——————————-
该类将使用现有 phone_number 数据表的属性。您可以与它交互,就好像已经手动定义了该类及其所有列一样,如前面的示例所示。使用 SQLObject,只需要编写表定义一次 —— 用 SQL 还是用 Python 编写就取决于您了。

但是,该特性又带来了数据库的选择问题。例如,该特性完全不能用于 SQLite。它基本上能用于 MySQL,但不能提取外键关系。如果使用的是 MySQL,而且想要为表定义外键,则需要在从数据库中加载模式之后,编写代码定义这些字段。

命名约定
上一部分中的代码假设现有表符合 SQLObject 的命名约定(例如,表的主键字段名为 id,且列名中的词用下划线分隔)。表的命名约定在 Style 类中定义。

SQLObject 提供了一些与常见数据库命名约定对应的 Style 类。例如,如果列名类似 likeThis 而非 like_this,则可以使用 MixedCaseStyle:
——————————-
import sqlobject
from sqlobject.styles import MixedCaseStyle
from Connection import conn
class PhoneNumber(sqlobject.SQLObject):
_connection = conn
_fromDatabase = True
_style = MixedCaseStyle
——————————-

如果没有预包装的 Style 类符合您的需要,那么您可以定义 Style 基类的子类,并定义自己的命名约定。在最坏的情况下,如果表的字段名分配得毫无道理,则可以逐个命名每个字段。

关于 SQLObject 限制
SQLObject 想让您用面向对象的方式而非关系方式进行思考。这有利于您的理解和您的编程生产率,但不利于性能。毕竟,数据库仍是关系型的。如何标记呼叫过的每个电话号码?使用 SQL,您将使用单个 UPDATE 命令。使用 SQLObject,您需要迭代通过整个结果集,并修改每个对象的 last_call 成员,这是非常低效的。

SQLObject 为开发人员时间牺牲了处理器时间。这通常是好的交易,但甚至在简单的应用程序中,您也可能需要下降一个级别到达 Python 数据库接口,为一些关键路径的操作编写原始 SQL。

2011年12月2日

SSH远程会话管理工具screen使用教程

by Nick Xu — Categories: LinuxLeave a comment

一、screen命令是什么?
Screen是一个可以在多个进程之间多路复用一个物理终端的全屏窗口管理器。Screen中有会话的概念,用户可以在一个screen会话中创建多个screen窗口,在每一个screen窗口中就像操作一个真实的telnet/SSH连接窗口那样。
二、如何安装screen命令?
除部分精简的系统或者定制的系统大部分都安装了screen命令,如果没有安装,
CentOS系统可以执行:
yum install screen
Debian/Ubuntu系统执行:
apt-get install screen
三、screen命令使用方法?
1、常用的使用方法
用来解决文章开始我们遇到的问题,比如在安装lnmp时。
1.1 创建screen会话
可以先执行:screen -S lnmp ,screen就会创建一个名字为lnmp的会话。
1.2 暂时离开,保留screen会话中的任务或程序
当需要临时离开时(会话中的程序不会关闭,仍在运行)可以用快捷键Ctrl+a d(即按住Ctrl,依次再按a,d)
1.3 恢复screen会话
当回来时可以再执行执行:screen -r lnmp 即可恢复到离开前创建的lnmp会话的工作界面。如果忘记了,或者当时没有指定会话名,可以执行:screen -ls screen会列出当前存在的会话列表。
11791.lnmp即为刚才的screen创建的lnmp会话,目前已经暂时退出了lnmp会话,所以状态为Detached,当使用 screen -r lnmp后状态就会变为Attached,11791是这个screen的会话的进程ID,恢复会话时也可以使用:screen -r 11791
1.4 关闭screen的会话
执行:exit ,会提示:[screen is terminating],表示已经成功退出screen会话。
2、远程演示
首先演示者先在服务器上执行 screen -S test 创建一个screen会话,观众可以链接到远程服务器上执行screen -x test 观众屏幕上就会出现和演示者同步。
3、常用快捷键
Ctrl+a c :在当前screen会话中创建窗口
Ctrl+a w :窗口列表
Ctrl+a n :下一个窗口
Ctrl+a p :上一个窗口
Ctrl+a 0-9 :在第0个窗口和第9个窗口之间切换

 

目标:终端使用 less/more/grep 等命令正确显示 GBK 编码文件内容,vim 正确显示 GBK 编码文件汉字

症状:

1. 系统自带 gnome-terminal 在设置终端编码为 GBK 后,能达到目标。

2. 使用 xshell 在 windows 平台上设置终端编码为 default 时,ssh 登录到 CentOS,能达到目标。

3. 在 screen 命令窗口内,无论终端还是 vim, 中文均显示为乱码,无法达到目标。

解决办法:在 ~/.screenrc 中,添加下面两句:

defencoding GBK
encoding UTF-8 GBK

我的猜测是 xshell、gnome-terminal 等终端能够将自身编码传给系统,因此系统能够对输出自动进行转码。而 screen 属于终端中的终端,它自身的编码不是 GBK,导致传给系统以后没有对输出进行转码。设置 screen 的编码和转换规则后,就 OK 了。

2011年11月17日

使用 python/django 发送iPhone push消息

by Nick Xu — Categories: PythonLeave a comment

iphone的push notification功能是个好东西,可以在一定程度上模拟后台运行程序的效果。但这个东西配置起来确实有点麻烦。好在apple的文档说的还算详细,仔细按照文档做,慢慢生成那一堆配置文件吧。

服务器端的配置:

在开发mac上,从keychain中将生成的keyexport出来,这里要注意要同时选中对应cer与private key两个项目,一起倒出到一个.p12文件中。

将倒出的p12文件放到服务器上,将p12文件转换为pem文件:

openssl pkcs12 -in cred.p12 -out cert.pem -nodes -clcerts
然后,按照 APNSWrapper 里的文档就可以测试了,随便使用一个token,如果没有异常就说明认证OK啦, APNSWrapper 真是个好东西。

http://code.google.com/p/apns-python-wrapper/

感谢互联网,感谢Python~~~

© 2012 So Tired!_! All rights reserved - Wallow theme v0.46.4 by ([][]) TwoBeers - Powered by WordPress - Have fun!
$1.99 Domains* at GoDaddy.com
֩` ֩` `ȥ Moncler Jackets Moncler Jackets Sale ֩` Moncler Monclair Moncler On Sale Moncler Online Outlet Moncler For Sale Monclers For Cheap Moncler Stores Moncler Cheap Authentic Moncler Jackets Moncler Outlets "Genuine Ugg Boots" Moncler Store moncler buy Moncler Jacket Down Down Jacket Moncler monclerforkids Moncler It Shop Moncler Uk Moncler Moncler Ski Mens Down Coat Jackets And Coats LeatherJackets For Men Real Ugg Boots "Classic Short Ugg Boots"
Abercrombie Sale Abercrombie Outlet Abercrombie Sale Abercrombie Jackets North Face Outlet ferragamo north face coat north face clothes ferragamo shoes timberland outlet spyder jackets paul smith spyder jacket salvatore ferragamo outlet spyder ski jacket tory burch sale Timberland Boots sale