How to Convert Python dict to object?

假如我们有如下的数据:

1
d = {'a': 1, 'b': {'c': 2}, 'd': ["hi", {'foo': "bar"}]}

假如我需要访问c需要通过d.get('b').get('c')

如果能直接通过d.b.c去访问就好了

实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
class Struct:
'''The recursive class for building and representing objects with.'''
def __init__(self, obj):
for k, v in obj.iteritems():
if isinstance(v, dict):
setattr(self, k, Struct(v))
else:
setattr(self, k, v)
def __getitem__(self, val):
return self.__dict__[val]
def __repr__(self):
return '{%s}' % str(', '.join('%s : %s' % (k, repr(v)) for
(k, v) in self.__dict__.iteritems()))

使用:

1
2
s = Struct(d)
s.b.c

提交代码时来张自拍

首先安装imagesnaphttps://github.com/alexwilliamsca/imagesnap或者Mac系统下通过homebrew安装:

1
brew install imagesnap

新建~/.gitshots目录:

1
mkdir ~/.gitshots

添加下面的文件post-commit到你代码目录的git hooks中:

1
2
3
4
5
6
7
#!/usr/bin/env ruby
file="~/.gitshots/#{Time.now.to_i}.jpg"
unless File.directory?(File.expand_path("../../rebase-merge", __FILE__))
puts "Taking capture into #{file}!"
system "imagesnap -q -w 3 #{file} &"
end
exit 0

为这个文件添加可执行权限:

1
chmod +x .git/hooks/post-commit

钩子(hooks)是一些在”$GIT-DIR/hooks”目录的脚本, 在被特定的事件(certain points)触发后被调用。当”git init”命令被调用后, 一些非常有用的示例钩子文件(hooks)被拷到新仓库的hooks目录中; 但是在默认情况下这些钩子(hooks)是不生效的。 把这些钩子文件(hooks)的”.sample”文件名后缀去掉就可以使它们生效了。

这样就可以了!😎


你还可以把这些图片合成为视频:http://www.dayofthenewdan.com/projects/tlassemble

我录的视频样例:http://7d9pyw.com1.z0.glb.clouddn.com/2015-11-26T23:49:57.198500_test.mov

原文链接:Take a photo of yourself every time you commit

GitHook参考:http://gitbook.liuhui998.com/5_8.html

Redis set中sadd插入时间测试

今天老郑问我“一个redis的set里面,最多能放多少数据,而不会有显著的性能下降?”,由于Redis中读取
的时间复杂度为O(1),增加的复杂度为O(n),这个问题还是有测试的价值的。

所以我直接写了下面这个测试用例来测试这个问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import unittest

import redis
import time


class RedisTest(unittest.TestCase):
def setUp(self):
self.redis_client = redis.StrictRedis()

def test_add_to_set(self):
for i in range(1000000):
start = time.time()
self.redis_client.sadd('test_set', i)
end = time.time()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
> python -m unittest tests/test_redis.py

... 省略了好多好多行
index: 999994, time: 0.00010895729064941406
index: 999995, time: 0.00014710426330566406
index: 999996, time: 0.00015497207641601562
index: 999997, time: 0.00015592575073242188
index: 999998, time: 0.00017213821411132812
index: 999999, time: 0.00010395050048828125
.
----------------------------------------------------------------------
Ran 1 test in 191.684s

OK

100W次插入,用时191.684s,平均每秒插入5216条数据,这个速度还是非常非常快的,所以放心用吧,
不用担心速度问题啦。

Stop / remove所有Docker容器笔记

一行代码停止或者删除全部的Docker容器

1
2
docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q)

个人笔记

docker stop为例,输入docker stop,显示

1
2
3
4
5
6
7
docker: "stop" requires a minimum of 1 argument.
See 'docker stop --help'.

Usage: docker stop [OPTIONS] CONTAINER [CONTAINER...]

Stop a running container.
Sending SIGTERM and then SIGKILL after a grace period

帮助说明docker stop 可以接受一个以空格分隔的容器数组,只要把全部的容器名称以空格连接就可以了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
> docker ps -a -q
Usage: docker ps [OPTIONS]

List containers

-a, --all=false Show all containers (default shows just running)
--before= Show only container created before Id or Name
-f, --filter=[] Filter output based on conditions provided
--format= Pretty-print containers using a Go template
--help=false Print usage
-l, --latest=false Show the latest created container, include non-running
-n=-1 Show n last created containers, include non-running
--no-trunc=false Don't truncate output
-q, --quiet=false Only display numeric IDs
-s, --size=false Display total file sizes
--since= Show created since Id or Name, include non-running

  • -a表示全部的容器
  • -q表示只显示容器ID

这样就可以取得全部的以换行符分隔的容器ID列表,再通过$()操作将换行符替换,就可以了。

Thinking in API

当时全世界只有一种语言和一样的话。
当人们由东方迁移的时候,在史纳尔地方找到了一块平原,就在那里住下了。
他们彼此说:「来,我们做砖,用火烧透。」他们遂拿砖当石,拿沥青代灰泥。
然后彼此说:「来,让我们建造一城一塔,塔顶摩天,好给我们作记念,免得我们在全地面上分散了!」
上主遂下来,要看看世人所造的城和塔。
上主说:「看,他们都是一个民族,都说一样的语言。他们如今就开始做这事;以后他们所想做的,就没有不成功的了。
来,我们下去,混乱他们的语言,使他们彼此语言不通。」
于是上主将他们分散到全地面,他们遂停止建造那城。
为此人称那地为「巴贝耳,」因为上主在那里混乱了全地的语言,且从那里将他们分散到全地面。

话说上帝为了让人类不能做他们所想于是混乱了大家的语言,使大家语言不通。我们写程序的也被各种不同的
语言所隔离,各不相通,同一个库不同的语言都有各自的实现,有好有差。大家为什么就不能都说同一个语言呢?
PHP的库我写Python时也想用,这难道不行吗?

我的想法是将各种库转换为我们程序员通过的语言,简单明了,就是emoji表情一样😂,以下是我的想法,有时间实现一下,
一个以API为中心的数据平台:

  • 数据通过JSON为数据序列化
  • 使用基于RESTful的HTTP请求进行通信(可以使用swagger
  • 统一的接口页面
  • 同风格的展示页面

如何在Ubuntu上通过Nginx设置HTTP认证

Apache Utils

我们需要htpassword来创建和生成加密的用户用于基础认证(Basic Authentication)。通过以下命令安装apache2-utils

1
sudo apt-get install apache2-utils

创建用户名和密码

在Nginx托管的网站目录下生成一个.htpasswd文件。如下的命令可以创建文件同步增加用户和加密的密码到文件中

1
sudo htpasswd -c /etc/nginx/.htpasswd exampleuser

命令行为提示你输入密码

1
2
3
New password:
Re-type new password:
Adding password for user exampleuser

htpaswd的文件格式如下:

1
login:password

注意:htpasswd需要对nginx运行用户可访问

更新Nginx配置

在你的网站的Nginx配置文件增加如下两行:

1
2
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;

第二行是你的htpasswd文件位置。

举个例子,假如你的文件是/etc/nginx/sites-available/website_nginx.conf,通过vi或者其它编辑器打开该文件

1
sudo vi /etc/nginx/sites-available/website_nginx.conf

增加代码:

1
2
3
4
5
6
7
8
9
10
server {
listen portnumber;
server_name ip_address;
location / {
root /var/www/mywebsite.com;
index index.html index.htm;
auth_basic "Restricted"; #For Basic Auth
auth_basic_user_file /etc/nginx/.htpasswd; #For Basic Auth
}
}

刷新Nginx

为了使配置生效,需要刷新nginx配置,然后再访问

1
2
$ sudo /etc/init.d/nginx reload
* Reloading nginx configuration...

原文:https://www.digitalocean.com/community/tutorials/how-to-set-up-http-authentication-with-nginx-on-ubuntu-12-10

如何打开MySQL查询日志?

首先找到MySQL的配置文件my.cnf,在[mysqld]下添加

1
general_log_file=~/query.log

同时,登录MySQL console中设置打开log

1
2
3
mysql -uroot

> SET global general_log = 1;

重启MySQL之后就可以在当前用户的HOME目录中通过query.log查看SQL日志了。

例如,当你执行use mysql; select * from user;

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
150729 11:51:43	   43 Connect	root@localhost on
43 Query select @@version_comment limit 1
150729 11:51:47 43 Query SELECT DATABASE()
43 Init DB mysql
43 Query show databases
43 Query show tables
43 Field List columns_priv
43 Field List db
43 Field List event
43 Field List func
43 Field List general_log
43 Field List help_category
43 Field List help_keyword
43 Field List help_relation
43 Field List help_topic
43 Field List innodb_index_stats
43 Field List innodb_table_stats
43 Field List ndb_binlog_index
43 Field List plugin
43 Field List proc
43 Field List procs_priv
43 Field List proxies_priv
43 Field List servers
43 Field List slave_master_info
43 Field List slave_relay_log_info
43 Field List slave_worker_info
43 Field List slow_log
43 Field List tables_priv
43 Field List time_zone
43 Field List time_zone_leap_second
43 Field List time_zone_name
43 Field List time_zone_transition
43 Field List time_zone_transition_type
43 Field List user
43 Query select * from user

参考:http://stackoverflow.com/questions/6479107/how-to-enable-mysql-query-log

MySQL错误 ERROR 2006 (HY000): MySQL server has gone away

MySQL下当我导入一个比较大的SQL文件时出现了ERROR 2006 (HY000): MySQL server has gone away错误,具体情况如下:

1
2
3
4
5
>  ll *.sql
-rwxr-xr-x@ 1 bohan staff 27M Mar 26 18:08 91620_all.sql

> mysql test < 91620_all.sql
ERROR 2006 (HY000) at line 17128: MySQL server has gone away

上面可以看到,文件大小为27M导入的时候会报这个错误。

错误原因

If you are using the mysql client program, its default max_allowed_packet variable is 16MB. To set a larger value, start mysql like this:

1
shell> mysql --max_allowed_packet=32M

That sets the packet size to 32MB.

我们通过MySQL相关文档可以发现默认大小是16M。

解决方法

所有大于16M的SQL文件都会报这个错误。

不过我们可以直接通过命令后增加--max_allowed_packet=32M解决

或者登录MySQL客户端,修改系统变量

1
2
> ssh mysql
mysql> set GLOBAL max_allowed_packet=32*1024*1024;

我们也可以通过修改MySQL配置my.cnf文件,在最后一行增加max_allowed_packet=32M就可以了

MySQL配置文件的位置:

  • Windows下 C:\ProgamData\MySQL\MySQL Server5.6
  • Linux下 /etc/mysql
  • Mac下通过brew安装 /usr/local/Cellar/mysql/5.6.23