终极算法

当你用网易云音乐查看推荐歌单的时候,当你在百度搜索信息的时候,当你在互联网金融平台申请借款的时候,甚至在你调戏Siri和小冰的时候,其实都是其背后的机器学习算法在云端服务器中为你默默服务。佩德罗·多明戈斯, 终极算法:机器学习和人工智能如何重塑世界, loc. 114-116. Kindle Edition

Continue Reading →

Django异常处理

基于django技术栈实现的WEB应用,生产环境中都会关闭DEBUG选项,Django默认只会输出很少的错误信息,不利于开发人员快速定位、解决问题。为了解决此问题,考虑定制Django默认的错误处理,还原错误现场,配合错误日志、邮件报警快速发现、解决BUG。

本文档不包含错误日志、邮件报警等内容

Django异常内容调用栈帧

WSGI处理函数

django.core.handlers.base.py

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
class BaseHandler(object):
# Changes that are always applied to a response (in this order).
... ...

def get_response(self, request):
"Returns an HttpResponse object for the given HttpRequest"
# Setup default url resolver for this thread, this code is outside
# the try/except so we don't get a spurious "unbound local
# variable" exception in the event an exception is raised before
# resolver is set
# 初始化路由解析器
urlconf = settings.ROOT_URLCONF
urlresolvers.set_urlconf(urlconf)
resolver = urlresolvers.RegexURLResolver(r'^/', urlconf)

try:
response = None
... ...
except: # Handle everything else.
# Get the exception info now, in case another exception is thrown later.
signals.got_request_exception.send(sender=self.__class__, request=request)
# 调用处理未捕获的异常方法
response = self.handle_uncaught_exception(request, resolver, sys.exc_info())
... ...
# 处理未捕获的异常
def handle_uncaught_exception(self, request, resolver, exc_info):
"""
Processing for any otherwise uncaught exceptions (those that will
generate HTTP 500 responses). Can be overridden by subclasses who want
customised 500 handling.
Be *very* careful when overriding this because the error could be
caused by anything, so assuming something like the database is always
available would be an error.
"""
if settings.DEBUG_PROPAGATE_EXCEPTIONS:
raise
logger.error('Internal Server Error: %s', request.path,
exc_info=exc_info,
extra={
'status_code': 500,
'request': request
}
)
if settings.DEBUG:
return debug.technical_500_response(request, *exc_info)
# If Http500 handler is not installed, re-raise last exception
if resolver.urlconf_module is None:
six.reraise(*exc_info)
# Return an HttpResponse that displays a friendly error message.
# 查找注册的错误处理函数
callback, param_dict = resolver.resolve_error_handler(500)
# 调用错误处理函数
return callback(request, **param_dict)
class WSGIHandler(base.BaseHandler):
def __call__(self, environ, start_response):
... ...
response = self.get_response(request)

URL路由解析

django.core.urlresolvers.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class RegexURLPattern(LocaleRegexProvider):
def __init__(self, regex, callback, default_args=None, name=None):
LocaleRegexProvider.__init__(self, regex)
# callback is either a string like 'foo.views.news.stories.story_detail'
# which represents the path to a module and a view function name, or a
# callable object (view).
if callable(callback):
self._callback = callback
else:
self._callback = None
self._callback_str = callback
self.default_args = default_args or {}
self.name = name

# 解析错误处理函数
def resolve_error_handler(self, view_type):
callback = getattr(self.urlconf_module, 'handler%s' % view_type, None)
if not callback:
# No handler specified in file; use default
# Lazy import, since django.urls imports this file
from django.conf import urls
callback = getattr(urls, 'handler%s' % view_type)
return get_callable(callback), {}

注册Django默认错误处理函数

django.confs.urls.__init__.py

1
2
3
4
handler400 = 'django.views.defaults.bad_request'
handler403 = 'django.views.defaults.permission_denied'
handler404 = 'django.views.defaults.page_not_found'
handler500 = 'django.views.defaults.server_error'

定义Django默认错误处理函数

django.views.defaults.py

1
2
3
4
5
6
7
8
9
10
11
12
@requires_csrf_token
def server_error(request, template_name='500.html'):
"""
500 error handler.
Templates: :template:`500.html`
Context: None
"""
try:
template = loader.get_template(template_name)
except TemplateDoesNotExist:
return http.HttpResponseServerError('<h1>Server Error (500)</h1>', content_type='text/html')
return http.HttpResponseServerError(template.render())

定制Django500异常处理

定制WSGIHandler

project/wsgi.py

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
class CustomWSGIHandler(WSGIHandler):
"""
定制WSGIHandler
"""
def handle_uncaught_exception(self, request, resolver, exc_info):
"""
重载夫类异常处理函数
"""
_logger = logging.getLogger('app.wsgi')
if settings.DEBUG_PROPAGATE_EXCEPTIONS:
raise
_logger.error('Internal Server Error: %s', request.path,
exc_info=exc_info,
extra={
'status_code': 500,
'request': request
}
)
# 不再返回500的异常HTML报文
# if settings.DEBUG:
# return debug.technical_500_response(request, *exc_info)
# If Http500 handler is not installed, re-raise last exception
if resolver.urlconf_module is None:
six.reraise(*exc_info)
# Return an HttpResponse that displays a friendly error message.
callback, param_dict = resolver.resolve_error_handler(500)
return callback(request, **param_dict)
def get_wsgi_application():
django.setup()
return CustomWSGIHandler()

定制500错误处理函数

project/error_handlers.py

1
2
3
4
5
6
7
@requires_csrf_token
def server_error(request, template_name='500.html'):
"""
定制500异常函数
"""
_logger.error('server_error.')
return http.HttpResponseServerError('Server Error')

注册500错误处理函数

protject/urls.py

1
handler500 = 'error_handlers.server_error'

注册ROOT_URLCONF

project/settings.py

1
ROOT_URLCONF = 'project.urls'

参考

MacOS安装PIL

MacOS安装PIL库

安装libjpeg

1
2
3
4
5
6
7
curl -O http://www.ijg.org/files/jpegsrc.v8c.tar.gz
tar -xvzf jpegsrc.v8c.tar.gz
cd jpeg-8c
./configure
make
sudo make install
cd ../

安装freetype

1
2
3
4
5
6
7
curl -O http://ftp.igh.cnrs.fr/pub/nongnu/freetype/freetype-2.4.5.tar.gz
tar -xvzf freetype-2.4.5.tar.gz
cd freetype-2.4.5
./configure
make
sudo make install
cd ../

安装PIL

1
2
3
4
5
6
curl -O -L http://effbot.org/media/downloads/Imaging-1.1.7.tar.gz
# extract
tar -xzf Imaging-1.1.7.tar.gz
cd Imaging-1.1.7
python setup.py install
cd ..

参考

SQL

MySQL数据库远程访问

1
2
GRANT ALL PRIVILEGES ON *.* TO 'USERNAME'@'%' IDENTIFIED BY 'PASSWORD' WITH GRANT OPTION;
FLUSH PRIVILEGES;

创建数据库

1
CREATE DATABASE database_name CHARACTER SET utf8;

导出数据库表

1
2
3
4
5
mysqldump -h127.0.0.1 -uusername -ppassword
database_name table_name > database_name.table_name.sql;

mysqldump -h127.0.0.1 -uusername -ppassword
database_name table_name --where="id>100" > database_name.table_name.sql;

导出数据库表结构

1
mysqldump  -hhost -P3306 -uusername -ppassword  database_name --no-data > db_name_schema.sql

导入数据库

1
2
3
mysql -h127.0.0.1 -uusername -ppassword database_name < database_name.table_name.sql;
mysql -uusername -ppassword;
> source sql_file_path;

数据从一张表导出到另一个张表

1
2
3
4
5
6
INSERT INTO database_name.table_name
(field1,
field2)
SELECT field1,
field2
FROM database_name.table_name;

根据一张表更新另一张表

1
2
3
4
UPDATE kdreader.library_book
INNER JOIN store_book
set kdreader.library_book.author_id=store_book.author_id
WHERE kdreader.library_book.name=store_book.titl;

修改表结构:增加Column

1
ALTER TABLE table_name_example ADD COLUMN field_name field_type DEFAULT default_value;

修改表结构:更新Column

1
ALTER TABLE table_name_example ALTER COLUMN field_name field_type DEFAULT default_value;

修改表结构:删除Column

1
ALTER TABLE table_name_example DROP COLUMN field_name;

修改表结构:删除unique约束

1
ALTER TABLE table_name_example DROP INDEX unique_key_name;

表重命名

1
ALTER TABLE old_name RENAME TO new_name;

增加Unique约束

1
ALTER TABLE Persons ADD CONSTRAINT uni_PersonID UNIQUE (Id_P,LastName);

分组查询

1
2
3
4
5
6
SELECT book_labels.label_id,
Count(book_labels.book_id) cnt
FROM store_book_labels AS book_labels
GROUP BY book_labels.label_id
ORDER BY cnt DESC
LIMIT 20;

Reference

安装Node.js

Linux

1
2
curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -;
sudo apt-get install -y nodejs;

Mac OSX

1
2
curl "https://nodejs.org/dist/latest/node-${VERSION:-$(wget -qO- https://nodejs.org/dist/latest/ | sed -nE 's|.*>node-(.*)\.pkg</a>.*|\1|p')}.pkg" > "$HOME/Downloads/node-latest.pkg" && sudo installer -store -pkg "$HOME/Downloads/node-latest.pkg" -target "/";
brew install node;

参考

旅行,写作,编程

花了10个月的时间做世界环游,途经非洲,东南亚,澳洲,中南美洲里的17个国家和地区。这次旅行的主题就是冲浪和摄影。
出席在香港,日本,美国和伦敦举行的会议
启程时给O’Reilly出版公司写了一本书,书名叫做《JavaScript Web Applications》
另外写了一本关于CoffeeScript的书,很快就会由O’Reilly公司出版。
写了大量的开源库,例如Spine, Spine.Mobile, GFX, 和 Juggernaut.
筹划了一个创业公司的框架
出席伦敦2011FOWA会议
最后,我在Twitter公司找到了一份工作
那么,让我从一年前开始,那是2010年9月,我刚好从一个我合作创办的公司里出来,尽管这段经历是很有价值的,但无休无止的长时间苦干让我精疲力 尽。我回到了英格兰,需要对未来做一些思考。我一直有一个梦想——移居美国(几年就好),所以,我在Google记事本上写了下面的话:

人生的选择:
去纽约哥伦比亚大学深造
坏处 - 非常昂贵,并不一定能学到什么真正有用的东西,无聊?
好处 - 那是一个纽约的大学!
写一本书,申请 01 签证
坏处 - 需要大量的时间,有风险
好处 - 对事业有好处,有趣
等待。去纽约度一次假(3个月)。等待创业签证。
很容易 - 不是那么有趣

也许选第二个,不行就选3?
最终我选择了2,我已经对JavaScript web应用研究了很久,我要写一本这方面的书,为什么不边做环游世界的旅行、边写书呢?这也是我一个梦想呀。我从oneworld买了一份环游世界的机票(比你们想象的要便宜),决定下周去我的第一站,南非。

如果你从来没有到过非洲,你应该去一次。那里的景色原始而美丽,对那些没有体验过这种景色的人,你很难用言语描绘明白。几年前我就喜欢上了南 方,那时我在东海岸做了一个为期3个月的冲浪旅行。这次,我只有一个月的时间,穿越特兰斯凯,从开普敦到德班。当我在南非旅行时,我的写作也开始了,把早 期向O’Reilly提交的书的框架里的数章填充了材料。

特兰斯凯是南非非常具有乡野特色的地方,到处是连绵的小山,一些小村庄和土堆的茅屋。他们仍然沿袭着酋长制度,有一个首领,大多数的当地人靠捕 鱼为生。我们在高低不平的土路上颠了两天才到达我心仪的地方,一个美丽的海湾,叫做咖啡湾(Coffee Bay)。在那里,我休整了一下,从网上下载了一些相关资料,为更远的海湾远征做准备。

我还清晰的记得我们走了数里地来到那个未开垦的海滩,我们从那些一个个被黄沙和小丘孤立的村庄穿行而过。有一个地方,我们要过一条大河,我们需 要游过去,我把背包举过头顶,以免里面的相机和iPod遇到水。非洲是一个让你脱离尘世的地方,解放你的思想,重新认识人生最重要的东西是什么。

下一站是香港,在那里,我度过了我的21岁生日,接着,我从陆路由新加坡到越南河内。很多人不相信香港70%的面积由自然公园覆盖,我徒步走了几条精彩的景观路线,非常的精彩壮观,比如:香港龙脊。有几天,我在boot.hk这个网站上闲逛,这是一个协作工作的网站,我顺便教了一个同行的游客如何使用ruby。然后,到了夜里,我跟Soho里的一些冲浪爱好者狂欢到凌晨。

从泰国到柬埔寨到越南是我这次旅行中做喜欢的部分,如果你从没有到过亚洲,你绝对应该去一次。这些国家非常的漂亮,气候非常的好,食物美味可口,人们非常友善。吴哥窟是世上最神奇的地方之一,每个人都应该去看看。是Trey Ratcliff的照片把我吸引到了那里,我的很多其它旅游目的地也是受了他的影响。那个家伙是很多旅游地的第一宣传者。

在一些无名的小博客中,我听有人说过一个很远的美丽的小岛,在柬埔寨的海边。说小岛的Sihanoukville这个地方有个酒吧,说只能坐小 渔船到那里。我,还有几个非常好的朋友,乘坐晚上的大巴,开始寻找这个传说中的酒吧。搜索差不多进行了一整天,每一个问过的酒吧都把我们指向另外一个酒 吧。最终,我们问了出来,并在第二天早晨做短程巴士去了那个地方。

上面的照片上是海岸边一个10美元一晚的小木屋。从当地居民区离开后,我们的队伍像小岛上唯一的人,我们随性自由的奔跑。白天我们懒懒的躺在海滩上,吃着岛上厨师准备的鲜美可口的水果沙拉,在夜晚,我们在到处是浮游生物的海里游泳。

下一站是越南,我们沿着湄公河支流来到一个边界上的小镇,我们是这里唯一的西方人,交流成了最大的问题。幸运的是,我们发现一个也许是镇上唯一会说英语的人,他骑车当我们的向导。当我的信用卡被那里的一个自动取款机吞掉了后,他提供了我很大的帮助!

我们的队伍分成了几路,在我到达越南时,我的书正在按计划完成,进行的非常顺利。此时,我在西贡多待了几周,让我在书的好几章上有了重大的进展,正好是中国旧历新年,气氛非常的壮观热闹。

接着是日本,澳大利亚,新西兰和夏威夷。我很难把我所有的感受都在这篇文章里写出来,但说这是此生难忘的一段历程是不为过的。把如此多的美景都 放到一个国家里,太让人赞叹了,我说的正是新西兰。我最喜爱的一段记忆是沿着Wanaka的一个湖边在阳光下跑步,还有就是背着食物和生活用品,徒步数天 穿越Routeburn的大山。在这个国家的旅途中,我结识了好几个值得一生相伴的好友。这是一个真正的天堂。

就在我环绕新西兰的南部岛屿时,我的书终于完成了,提交给了技术编辑校对。

接下来是纽约和旧金山,这两个神奇的地方到处是天才的程序员,有些人我很幸运的认识。Techcrunch Disrupt办的很精彩(我高度推荐hackathon)。

在从纽约到旧金山的中途停留期间,我在各种公司了进行了不少的求职面试,最终在Twitter公司找到了一份做前端开发的工作。要在那里和杰出的团队一起工作,我不能不高兴的颤抖,而去旧金山,同样也是我此生的一个梦想。

当签证的事办下来了后,我去了中、南美洲旅行,同时开发了我的一个小工程:一个JavaScript MVC框架库,叫做Spine。我到了哥斯达黎加,巴拿马,秘鲁,Bolvia,和阿根廷。 秘鲁是我的最爱,尽管那里的海拔给我带来了不少麻烦,我大部分的时间都在探险。下面的图片是哥斯达黎加传说中神奇猎鹰,是在我爬下世界最深的峡谷时拍到的。

当我在哥斯达黎加时,微博上有个叫Roberto的家伙给我发了条信息,说他读了我的书,问我是否有兴趣一起冲浪。我欣然同意,坐上去圣何塞的 汽车,在几天后和他会了面。那天我们一起在他海边的公寓里开发Spine和Ruby项目,使用移动硬盘,用汽车电源给笔记本充电。当电量不足后,让太阳能 板补充能量,我们去冲浪。

我推荐大家去写一本书,特别是边旅游边写书。可以想象,如果我不去旧金山去看一看,我可能还在旅途中,做顾问,去创业。当作家并不能让你直接的 挣到很多钱,但它绝对能提升你的身份地位,给你带来很多潜在的机会。事实上,写作过程让我真正享受的是,我可以认真深入的研究一个题目。

这一年是我这辈子目前为止最好的一年,而我感觉今后的一年会更好。当我如今定居下来后,我并没有感觉旅行对我的吸引力减少了;我始终把签证放到一个口袋里,而另一个口袋里装着钱包,当召唤降临,随时准备离开。

可是,这篇文章并不是关于我的旅行,它是要发送一个信号:

对于程序员来说,有个得天独厚的条件,就是这种职业可以远程工作或边旅游边工作,这是其它职业办不到的。当然,也不都是这样,在我的旅途中,我 没有碰到第二个跟我的做法相似的程序员。这种情况让人悲哀。我想向程序员们送出的信息是,不要再找借口了,行动起来,你可以做到。一个人只有一生,我可以 向你保证,这样的生活才不枉世间走这一遭。

就像我,我感到极度的幸运,能这样的生活,去发现我的热情所在,去做每天我喜欢做的事情。你可以看出,大部分我现在的境遇并非偶然或侥幸,这是计划,追求,工作的结果。

一份汗水,一份收成。

这篇文章的目标不是做一些自我陶醉似的炫耀和大话,而是向大家演示如何立下目标,鼓励大家去做相似的事情。想清楚你现在的处境,这一年内你想得到什么,制定出一系列具体的能让你到达这些目标的步骤。追随你的梦想。

原文地址:https://www.oschina.net/news/23952/traveling_writing_programming

Django QuerySet

字段查找过滤

操作符 含义
__exact 精确等于 like ‘aaa’
__iexact 精确等于 忽略大小写 ilike ‘aaa’
__contains 包含 like ‘%aaa%’
__icontains 包含 忽略大小写 ilike ‘%aaa%’,但是对于sqlite来说,contains的作用效果等同于icontains。
__gt 大于
__gte 大于等于
__lt 小于
__lte 小于等于
__in 存在于一个list范围内
__startswith 以…开头
__istartswith 以…开头 忽略大小写
__endswith 以…结尾
__iendswith 以…结尾,忽略大小写
__range 在…范围内
__year 日期字段的年份
__month 日期字段的月份
__day 日期字段的日

Reference

当我跑步时,我谈些什么

在肉体上时痛苦的,在精神上,令人沮丧的局面有时也会出现。不过,“痛苦”对于这一运动,乃是前提条件的东西。不伴随着痛苦,还有谁来挑战铁人三项赛事和全程马拉松这种费时耗力的运动呢?正因为痛苦,正因为刻意经历者这种痛苦,我才从这个过程中发现自己还活着的感觉,至少是发现了一部分。我现在意识到:生存的质量并非成绩、数字、名次之类固定的东西,而是含于运动中流动性的东西。