三体3:死神永生

三体3:死神永生 三体危机的出现,使全人类第一次面对一个共同的敌人,对联合国的 期望自然提高了。即使是保守派也认为,联合国应该进行彻底的改革并 被赋予更高的权力和支配更多的资源,激进派和理想主义者则鼓吹成立 地球联邦,联合国成为世界政府。中小国家更热衷于联合国地位的提升, 危机在他们眼中是一个从大国获得技术和经济援助的机会;而大国则对 此反应冷淡。事实上在危机出现后,大国都很快在太空防御的基础研究 上进行了巨大的投入,一方面因为他们意识到,太空防御是未来国际政治 的重要领域,在其中的作为将直接关系到国家实力和政治地位的基础;另 一方面,这些大型基础研究是早就想做的,只是由于国计民生和国际政治 的限制而一直做不了。现在,三体危机对于大国政治家们来说,就相当于 当年的冷战对于肯尼迪,但这个机会比那次要大百倍。不过各大国都拒 绝把这些努力纳入联合国的框架。由于国际社会日益高涨的世界大同热, 他们不得不给联合国开出了许多空头的政治支票,但对其倡导的共同太 空防御体系却投入很少。《三体Ⅲ死神永生》, loc. 498-507. Kindle Edition

Continue Reading →

三体2:黑暗森林

三体2:黑暗森林, 刘慈欣 “你看,星星都是一个个的点,宇宙中各个文明社会的复杂结构,其中的混沌和随机的因素,都被这样巨大的距离滤去了,那些文明在我们看来就是一个个拥有参数的点,这在数学上就比较容易处理了。”刘慈欣, 三体2:黑暗森林, loc. 92-94. Kindle Edition “所以你最后的成果就是纯理论的,就像欧氏几何一样,先设定几条简单的不证自明的公理,再在这些公理的基础上推导出整个理论体系。”刘慈欣, 三体2:黑暗森林, loc. 95-97. Kindle Edition “第一,生存是文明的第一需要;第二,文明不断增长和扩张,但宇宙中的物质总量保持不变。”刘慈欣, 三体2:黑暗森林, loc. 98-99. Kindle Edition

Continue Reading →

三体

三体, 刘慈欣 令汪淼惊奇的是她竟穿着一套“V装具”。这是目前在游戏玩家中很流行的玩意儿,由一个全视角显示头盔和一套感应服构成,感应服可以使玩家从肉体上感觉到游戏中的击打、刀刺和火烧,能产生出酷热和严寒,甚至还能逼真地模拟出身体暴露在风雪中的感觉。刘慈欣, 三体, loc. 418-421. Kindle Edition

Continue Reading →

终极算法

当你用网易云音乐查看推荐歌单的时候,当你在百度搜索信息的时候,当你在互联网金融平台申请借款的时候,甚至在你调戏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