Archive for 算法-编程

执行系统命令一般都是os.system(),但是我想返回编译c语言程序的结果,找到一个os.popen()发现不行,又找到一个commands.getoutput成功解决了。 官方文档: http://docs.python.org/2/library/subprocess.html#module-subprocess

Continue

参考资料: http://eshlox.net/en/2012/09/11/nginx-uwsgi-virtualenv-and-django-ubuntu-1204/ https://virtualenv-chinese-docs.readthedocs.org/en/latest/ https://uwsgi.readthedocs.org/en/latest/tutorials/Django_and_nginx.html http://www.virtualenv.org/en/latest/ 在virtualenv环境下安装 mysqldb的时候遇到几个问题 $ sudo apt-get install libmysqlclient-dev $ sudo apt-get install python-dev   把第一个链接的文章转过来,防止以后不能访问,其他几个都是官方文档,主要还是参考官方文档。 First install required applications.

sudo apt-get install nginx uwsgi uwsgi-plugin-python python-virtualenv
Versions of packages that will be used:
Nginx 1.1.19.1
Uwsgi 1.0.3+dfsg-1ubuntu0.1
Virtualenv 1.7.1.2-1
Django 1.4.1
Virtualenv. I store my project in ~/projects. Now I'm creating python virtual environment for my project and I'm installing Django.
cd ~/projects/
virtualenv eshlox.net
cd eshlox.net
source bin/activate
pip install django
django-admin.py startproject project
Nginx configuration. IMHO, by default, nginx is configured for basic tasks. I won't change this configuration in this entry. Configuration files are stored in /etc/nginx/sites-available. Go to this directory and create a new file.
cd /etc/nginx/sites-available
vim eshlox.net
It's example configuration.
server {
    listen  80;
    server_name eshlox.net www.eshlox.net;
    access_log /var/log/nginx/eshlox.net_access.log;
    error_log /var/log/nginx/eshlox.net_error.log;

    location / {
        uwsgi_pass  unix:///tmp/eshlox.net.sock;
        include     uwsgi_params;
    }

    location /media/  {
        alias /home/eshlox/projects/eshlox.net/project/project/media/;
    }

    location  /static/ {
        alias  /home/eshlox/projects/eshlox.net/project/project/static/;
    }
}
We must create symlink to enable this.
cd /etc/nginx/sites-enabled
ln -s ../sites-available/eshlox.net .
Uwsgi. Like with Nginx.. configuration files are stored in /etc/uwsgi/apps-available. Go to this directory and create a new file.
cd /etc/uwsgi/apps-available
vim eshlox.net.ini
[uwsgi]
vhost = true
plugins = python
socket = /tmp/eshlox.net.sock
master = true
enable-threads = true
processes = 2
wsgi-file = /home/eshlox/projects/eshlox.net/project/project/wsgi.py
virtualenv = /home/eshlox/projects/eshlox.net
chdir = /home/eshlox/projects/eshlox.net/project
touch-reload = /home/eshlox/projects/eshlox.net/project/reload
Enable this.
cd /etc/uwsgi/apps-enabled/
ln -s ../apps-available/eshlox.net.ini .
That's all. Now, run this services.
sudo service nginx start
sudo service uwsgi start
Of course, this is a very basic configuration. Change it according to your needs.

Continue

还是从helloworld里,application = tornado.web.Application([(r"/", MainHandler),]),然后看类Application。 参数 transforms用于头信息的定义,列表存储处理类名。ChunkedTransferEncoding,GZipContentEncoding继承自OutputTransform,可以实例化类的时候传入参数transforms,想gzip的启用可以使用setting,例如:settings = {'gzip': True}传入settings参数。 handlers列表,元素为(regexp, request_class)元祖。 settings,还可以设置static_path来标明静态文件访问路径,static_url_prefix标明访问前缀,没有默认设置"/static/"。给添加静态文件访问路由。最后合并参数中 的handlers。这里有一个StaticFileHandler类,等会儿看。 再往下是否载入自动更新模块,通过settings中debug设置。autoreload最最后再看吧。。初始化结束 方法 add_handlers。添加路由协议。983行,self.handlers[-1][0].pattern这里开始没看懂,后来看了re的文档才知道,这里几个变量也容易搞混,不易看懂。self.handlers只能通过,add_handlers进行添加。所以在__init__里面执行add_handlers的时候,self.handlers为空列表。983行 if self.handlers and self.handlers[-1][0].pattern == '.*$':判断只会执行if self.handlers。而当后来进行add_handlers的时候,self.handlers不为空,后面self.handlers[-1][0]类型为正则匹配的类型(我也不知道具体啥名,用type为SRE_Pattern与文档的不一样),可以使用.pattern返回匹配用的字符串进行比较。 这里的功能是为了让‘.*$’匹配放到规则的最下边,这个匹配是域名匹配,路径匹配在handlers,是一个列表,可变对象。在往下就是想handers列表中添加匹配规则,类型URLSpec。具体格式可以打印,先看看类URLSpec。再往下是添加named_handlers,用来通过reverse_url方法,使用name返回匹配的url路径,这个name也是在URLSpec。 URLSpec中self._path, self._group_count的用处现在还不清楚,其他几个上边都有介绍。self._path是把url路径中所有要匹配的替换成%s。self._group_count需要匹配 的数量。reverse方法就是将args带入到self._path。 UIModule类 定义同一类页面的显示。现在还没看到在哪里初始化和使用,Application中_load_ui_methods,_load_ui_modules通过settings设置对应的属性。 _get_host_handlers,__call__在我看完RequestHandler类之后再看,还有web.py其他的类一起。 通过修改helloworl打印一些信息,帮助理解代码:

import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import os.path

from tornado.options import define, options

define("port", default=8888, help="run on the given port", type=int)

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

def main():
    tornado.options.parse_command_line()
    settings = {'gzip': True, 'debug': True,
                'static_path': os.path.join(os.path.dirname(__file__), "static"),
                }
    application = tornado.web.Application([
        (r"/", MainHandler),
    ], **settings)
    print application.transforms
    print repr(application.handlers)
    h = application.handlers[0][0]
    print h.pattern
    for i in application.handlers[0][1]:
        print i.regex.pattern, i.handler_class

    http_server = tornado.httpserver.HTTPServer(application)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

if __name__ == "__main__":
    main()

Continue

下载了tornado 0.1的代码进行学习,之所以选择tornado,是看网上对非阻塞模式评价很高,他也不仅仅是web框架,而且相对django来说代码少多了(django的代码也有看)。选择0.1的原因还是代码相对简单,差别也不大。 查看demos里的helloworld,代码如下:

import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import logging

from tornado.options import define, options

define("port", default=8888, help="run on the given port", type=int)

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

def main():
    tornado.options.parse_command_line()
    application = tornado.web.Application([
        (r"/", MainHandler),
    ])
    http_server = tornado.httpserver.HTTPServer(application)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

if __name__ == "__main__":
    main()
从options倒入options和define。先看看官方的描述: 命令行解析模块,来定义使用参数。 例如:上边代码中define("port", default=8888, help="run on the given port", type=int)这句,当年在终端输入helloworld.py --help的时候,将会有“--port                           run on the given port (default 8888)”的提示。 tornado.options.parse_command_line()这一行是对命令行进行解析,格式:("--myoption=myvalue")。也可以是配置文件解析tornado.options.parse_config_file("/etc/server.conf"),配置文件必须是python文件,像: myoption = "myvalue" myotheroption = "myothervalue" 参数指定类型type可以是:datetimes, timedeltas, ints, and floats。 主要说_Options()和_Option() 344行实例化了类_Options,options = _Options.instance(),options现在为空字典,以后将 存储所有选项,通过上边提到的三种方式,添加是只通过define()。 _Option的参数来自define,metavar选择类型的参数,multiple=True会解析多个值,结果列表保存。 这个类里有个有parse()方法,学到很多知识。主要用于解析命令行下的参数,需要将选项对应的类型进行转换,作者使用_parse={type:parse_option_func}.get(type,type)的方法,然后通过_parse(value)进行解析转换参数。没有定义过的解析方法就直接使用type(value)转换了,只能说作者好强大。 代码的最后定义了几个默认设置。0.1的里面有help和logging。 对于options模块里的log代码等下一次总结,剩下的几个函数就很简单了,就不记录了。

Continue

由于Google reader的关闭,这段时间接触rss的东西相对多很多。试过qq的reader,不怎么样,阅读速度没有,是否阅读的标记也没有。其他网站的不想用,又要多注册账户。 找到python的rss处理包feedparser,官方文档很详细。http://pythonhosted.org/feedparser/ >>> import feedparser >>> d = feedparser.parse('http://0x55aa.sinaapp.com/feed') >>> a = d.feed >>> a.title 可以使用keys来查看字典键,可以很清楚的弄懂每一个的意思。官方文档上每一个都有介绍。 >>> d['feed'].keys() rss订阅的文章在d.entries里面是一个列表。 详细使用和高级用法见feedparser官方文档。

Continue

先说说我以前的做法:models.py里单纯的就是几个表,几个字段;forms.py里除了除了form的定义,把form数据的验证也放到这里来;view.py里是剩下的所有东西。 现在的想法(还没做):在models.py里面的类加上一些简单的处理方法,比如获取相关分类表里面的名称。forms.py里面加上save操作。 以前在django群里讨论过这个问题,大牛说逻辑处理最好不要放到views里面。这次写程序,又多瞅了几眼文档,感觉这样的好处确实很多,程序更容易读懂,减少代码行数,提高了代码复用,views.py文件肯定更加清晰。  

Continue

1.下载gtk+. http://ftp.acc.umu.se/pub/gnome/binaries/win32/gtk+/ 2.解压到d盘,添加环境变量D:\gtk\bin 3.测试gtk+。命令行输入:pkg-config --cflags gtk+-2.0或者gtk-demo 4.下载mingw http://sourceforge.net/projects/mingw/files/MinGW/ 5.双击安装,安装环境我选择了C Compiler & C++ Compiler & MSYS Basic System & MinGW Developer ToolKit,这里要用到mysys等工具。下载安装完后添加环境变量:D:\MinGW\bin。 6.测试mingw:可以在命令行下输入 gcc -v。

#include 

int main( int   argc,
          char *argv[] )
{
    GtkWidget *window;

    gtk_init (&argc, &argv);

    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_widget_show  (window);

    gtk_main ();

    return 0;
}
'gcc base.c -o base `pkg-config --cflags --libs gtk+-2.0`,打开MinGw Shell输入以上命令,就可编译完成,运行base.exe,成功。 以前想学pygtk的,现在自己用python写个工具就要依赖n多包,以后换个地方就要重新安装,很烦。给别人写的时候,又要打包程序很大,很不爽。再者说,接口应该都差不多。

Continue

正在编写的程序用的很多Windows下的操作,查了很多资料。看到剪切板的操作时,想起以前想要做的一个小程序,当时也没做,现在正好顺手写完。 功能:按printscreen键进行截图的时候,数据保存在剪切板里面,很不方便。比如游戏的时候截一个瞬间的图片,但你不能退出游戏保存图片,不方便多次截图。而我也不喜欢安装各种软件,所以准备写这个工具。 思路:一个是自定义快捷键,截图,保存。考虑到很可能各种冲突,取消。然后还是用按printscreen来截图,然后从剪切板读取图片数据,保存。想法是,先监听键盘按键,当printscreen按键时,读取剪切板内容,最后保存图片到指定位置。 1 监听键盘按键:从网上找到资料,安装pywin32,pyhook。链接:http://sourceforge.net/projects/pyhook/,http://sourceforge.net/projects/pywin32/。教程:http://sourceforge.net/apps/mediawiki/pyhook/index.php?title=PyHook_Tutorial。 2 读取剪切板内容,也是需要pywin32.文档在:[Pythonpath]\Lib\site-packages\PyWin32.chm,在线的:http://timgolden.me.uk/pywin32-docs/index.html 文档中给出的几种格式都不是图片保存的数据,Google搜索“Standard Clipboard Formats”,链接:http://msdn.microsoft.com/en-us/library/windows/desktop/ff729168%28v=vs.85%29.aspx,所有的格式,主要就是1-17. 好在文档中有一个函数:GetPriorityClipboardFormat,可以返回剪切板中的格式,从一个迭代器中。于是手动输入找到了,y有时为6,win32con.CF_TIFF,还会为2。当然这里直接用返回数据就行了,不需要知道是什么。 主要用到: OpenClipboard,CloseClipboard,GetPriorityClipboardFormat,GetClipboardData,这几个函数文档都有介绍,主要说说CloseClipboard,官方文档上讲,不要在剪切板里放置对象后调用CloseClipboard。 3 保存图片: 到这里发现可以直接用PIL模块,直接解决问题,上面太曲折T_T。 可以直接使用ImageGrab.grab() 进行抓屏,或者使用ImageGrab.grabclipboard()从剪切板获取图像。   最后变成,监听按键,按下printscreen后,用pil截图保存。T_T 感觉还不如设置快捷键,这样应该少占用内存。 cut.py

Continue

又传到github上了:https://github.com/0x55aa/golang-udp-chat 用golang写的第二个程序,这么久再没学golang,找到《go语言编程》的电子版,现在打算重新再学一遍。翻出这个程序,分享。 没有什么特殊功能,自己边做边添加,主要使用了net包中关于upd的几个函数。还没有实现预期的功能,只是个雏形,传上去好记得还写过这么个小程序,哪天心血来潮再改改。 程序是根据这个程序修改的《Network programming with Go》,下面我想看完电子书开始用go写web程序,路漫漫其修远兮 吾将上下而求索。 截了client的图: golang聊天程序

Continue

PyStringObject需要保存字符串长度(ob_size),当产生字符串对象后,将不会改变(不可变对象)。这一特性使得PyStringObject对象可作为dict的键值,同时也使一些字符串操作的效率大大降低了,比如字符串连接操作。   typedef struct { PyObject_VAR_HEAD long ob_shash; int ob_sstate; char ob_sval[1]; } PyStringObject;   同c语言一样,字符串末尾以‘\0’结尾,但是中间可以出现’\0’,ob_sval指向一段长度为ob_size+1个字节的内存,字符串结束需要满足ob_sval[ob_size] == ‘\0’   Ob_hash缓存该对象的hash值,初始值为-1。Ob_sstate在书后面介绍intern机制,对于被intern之后的字符串,在整个python运行期间,系统中都只有唯一一个与该字符串对应的PyStringObject对象。当判断两个PyStringObject对象是否相同时,如果都被intern了,只要检查对应的对象是否相同即可。   PyStringObject对应的类型对象为PyString_Type,tp_itemsize被设置成sizeof(char),即一个字节。与ob_size共同决定申请多少内存。 字符串对象有长度限制,大小为2GB。   Intern机制对相同字符串的处理: a = “python” b=”python” print a,b   intern机制的关键,是有一个叫interned的字典,记录intern机制处理过的PyStringObject对象。 对于上面的例子,先创建PyStringObject对象a,先会检查interned字典里有没有字符串与a相同,这里显然没有,将会添加到interned字典里。当创建b后(必须先要创建)执行intern操作,继续检查interned字典,发现有相同的字符串对象a,然后指向b的PyObject指针将指向a,b的引用计数减1,b将会被回收了。   有长度为256的字符缓冲池,添加到缓冲池的流程:当在创建PyStringObject对象时(还没创建),先检查长度。为字符时,再检查字符缓冲池是否有该字符,有,直接返回缓冲的该对象,结束;没有,创建PyStringObject对象,检查长度为字符,对对象进行intern操作,最后缓存至字符缓冲区。创建StringObject的两个函数不是太长也有注释,还能看懂。   字符串连接 通过”+”操作符对字符串进行连接是,调用string_concat函数:先计算连接后的字符串的长度,然后创建新的字符串对象分配给他计算的长度内存,最后复制。 Join操作,调用函数string_join:基本流程和“+”操作符相同。这里的区别是,“+”操作符有两个字符串就要创建一个新对象,join是对列表中的所有字符串进行,只要创建一次新对象就行。当进行多个字符串的连接时,应使用join操作。  

Continue