Wednesday, December 17, 2014

[Python] Class间大小比较(达到全序)

在Python 2.x中, 可以方便的使用 __cmp__ 方法来实现class object之间的大小比较.
class Foo:
    def __init__(self, key):
        self.key = key

    def __cmp__(self, other):
        return cmp(self.key, other.key)
如此Foo类型的object间的大小比较就可以用key这个域的值来实现.

在Python 3以后, __cmp__ 方法被移除了. 实现Foo object间的大小比较, 需要用functools.total_ordering修饰这个class以后, 实现__eq__方法以及__lt__(或者__lt__, __le__, __gt__, __ge__中的任意一个).
import functools

@functools.total_ordering
class Foo:
    def __init__(self, key):
        self.key = key

    def __eq__(self, other):
        return self.key == other.key

    def __lt__(self, other):
        return self.key < other.key

Saturday, August 09, 2014

Base64 Encoding

base64 encode是一种编码方式. 这种编码方式用来将一段二进制数据变换成为"方便传输"的文本数据. 它的核心思想是把二进制数据按每3个字节划分为一段, 然后每一段里每6个bit映射为一个文本字符来表示. 6个bit最多只有64种可能, 所以可以用a-zA-Z0-9+/ 这64个大多数字符集里都有的文本来对应.
在Objective C中, 使用如下的方法可以在二进制数据(NSDate类型)和based64 encoded数据(保存在NSString中)相互转换.
// From binary data to base64 encoded string
NSString string;
if ([data respondsToSelector:@selector(base64EncodedStringWithOptions:)]) {
    string = [data base64EncodedStringWithOptions:kNilOptions];  // iOS 7+
} else {
    string = [data base64Encoding];                              // pre iOS7
}

// From base64 encoded string to binary data
NSData *data;
if ([NSData instancesRespondToSelector:@selector(initWithBase64EncodedString:options:)]) {
    data = [[NSData alloc] initWithBase64EncodedString:string options:kNilOptions];  // iOS 7+
} else {
    data = [[NSData alloc] initWithBase64Encoding:string];                           // pre iOS7
}

Tuesday, August 05, 2014

[iOS] iOS开发涉及到的Certificate, Provisioning Profile

iOS development/distribution

iOS开发最基本的证书. 其实是一个private key, Xcode使用该private key对App的code签名.
  • iOS Development Certificate: 该证书用来在Xcode上开发一个iOS app
  • iOS Distribution Certificate: 该证书用来将一个iOS使用App Store或者AdHoc方式来分发给用户
每一个Certificate可以对应多个App.

iOS Push service

一个经过Apple授权的SSL Certificate, 使得App后端的notification server可以连接到Apple的APNS服务.
  • APNS Development SSL Certificate: 在开发测试期使用该证书. APNS的sandbox 服务器:gateway.sandbox.push.apple.com:2195
  • APNS Production SSL Certificate: 在App运行期使用该证书. 并连接APNS production 服务器:gateway.push.apple.com:2195
每一个特定的SSL Certificate只能对应一个iOS App ID.

什么是Provisioning Profile

一个被Apple使用PKCS#7标准签名过的plist文件. 这个plist文件里以key-value pair的形式保存了关于这个App的一些基本属性. 比如AppIDName,证书创建和过期日期等等. 每一个Provisioning Profile需要对应
  • 一个AppID
  • 一个development/distribution certificate

验证一个Provisioning Profile

$ openssl smime -in /path/to/your/foo.mobileprovision -inform der -verify 
这个命令会输出该plist文件的文本内容, 以及"Verification successful" 如果验证成功

参考

Thursday, July 17, 2014

SSL certificate

记点笔记
什么是SSL? https协议如运作:
http://www.tldp.org/HOWTO/SSL-Certificates-HOWTO/x64.html

检查你的server上的SSL certificate是否有效:
http://www.digicert.com/help/

创立一个self-signed ssl certificate:
http://www.akadia.com/services/ssh_test_certificate.html

Wednesday, May 21, 2014

[git] 建立以及使用Git的bare repo

git repo分为bare和non-bare两种. non-bare repo最最常见, 它包括一个working tree(你提交到这个git repo里的文件和目录结构)以及一个.git文件夹(其中有各种git系统文件). 而bare repo仅仅有系统文件. 一般在git server上,所有的repo都是以bare形式存在的. 通常除了admin以外,大家是不需要和bare repo打交道的.

不过事事无绝对, 我就在工作中遇到这样的一个问题需要和bare repo打交道: 我的所有源代码都放在一个远端的git的repo(比如放在github上), 可是由于某些缘故我或者不能或者不愿意在我工作环境里直接和github上的repo同步. 一个折衷的方案就是在一台自己的server上建立这个github上的repo, 然后在我的工作环境中首先和server上得 repo同步, 然后再登陆到server上把server里地repo和github上的repo同步.
这样造成的问题就是server上的repo必须得是bare. 如果它含有working tree, 那么就算将server上的repo里的.git目录作为upstream加入, pull的时候没有问题, 但push的时候也会有问题
$ git remote add some_remote_name ssh://apc999@myhost/home/apc999/some-repo/.git
$ git pull some_remote_name master
.. works file ...
$ git push --set-upstream ssh://apc999@myhost/home/apc999/some-repo/.git master
...
 ! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to '/home/apc999/some-repo'

如何使用bare repo

1 建立一个bare的git repo

$ git clone --bare my_project_on_github my-project.git
注意上面命令和普通git clone不一样的地方在于参数--bare. 普通的git clone命令会生成一个working tree和.git文件夹, 而--bare这样复制出来的bare repo就不包括working tree.

2 bare和 non-bare repo的转换

比如你的/home/apc999/my-project是一个git working tree
$ cd /home/apc999/my-project
$ git config --bool core.bare true

3 更新bare repo

注意, 在一个bare repo里, 不能使用git pull来更新这个repo. 而需要使用git fetch

Sunday, April 20, 2014

小米盒子使用记录

新拿到小米盒子, 记录并分享一下装机和使用心得.

开箱照


简朴的可回收硬纸壳包装, 电源, 连接电视的HDMI, 遥控器. 小米盒子说白了其实就是一个跑Android的小电脑, 只是它需要使用电视作为显示器.

推荐App

小米盒子有一个micro-USB接口. 所以接上U盘后, 就可以直接读取并安装U盘里存储的apk文件. 如下图所示:

这里是些常用的App:

参考

Saturday, April 19, 2014

[MacOS] MacOS 10.9(Mavericks)上clang对未知参数报错的问题

在MacOS 10.9上用pip安装一个库的时候发现clang报错
$ sudo pip install mysql-python
cc -fno-strict-aliasing -fno-common -dynamic -arch x86_64 -arch i386 -g -Os -pipe -fno-common -fno-strict-aliasing -fwrapv -mno-fused-madd -DENABLE_DTRACE -DMACOSX -DNDEBUG -Wall -Wstrict-prototypes -Wshorten-64-to-32 -DNDEBUG -g -fwrapv -Os -Wall -Wstrict-prototypes -DENABLE_DTRACE -arch x86_64 -arch i386 -pipe -Dversion_info=(1,2,5,'final',1) -D__version__=1.2.5 -I/usr/local/Cellar/mysql/5.6.16/include/mysql -I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c _mysql.c -o build/temp.macosx-10.9-intel-2.7/_mysql.o -Os -g -fno-strict-aliasing

clang: error: unknown argument: '-mno-fused-madd' [-Wunused-command-line-argument-hard-error-in-future]

clang: note: this will be a hard error (cannot be downgraded to a warning) in the future

error: command 'cc' failed with exit status 1

原因

XCode 5.1 以后, XCode的默认编译器clang会对所有它不认识的命令行flag报错 http://kaspermunck.github.io/2014/03/fixing-clang-error/

解决方法

参照这里给出的方案: http://stackoverflow.com/questions/22313407/clang-error-unknown-argument-mno-fused-madd-python-package-installation-fa

在运行安装命令的时候先修改CFLAGS和CPPFLAGS
$ export CFLAGS=-Qunused-arguments
$ export CPPFLAGS=-Qunused-arguments
$ sudo -E pip install mysql-python
注意由于安装过程中需要sudo, 所以为了让环境变量传递过去, 需要加上-E选项

[MacOS] 在MacOS 10.9(Mavericks)设置Apache/PHP

本来想自己写的. 但这篇实在写的太详实太好了.
http://www.coolestguidesontheplanet.com/downtown/get-apache-mysql-php-and-phpmyadmin-working-osx-109-mavericks
就捡几个重点的供我自己查询吧:

启动/关闭/重启apache server

$ sudo apachectl start
$ sudo apachectl stop
$ sudo apachectl restart

几个重要的文件和路径

  • 设置文件
    • httpd的全局设置文件:/etc/apache2/httpd.conf
    • 用户apc999的设置文件:/etc/apache2/users/apc999.conf
  • apache的日志
    • /var/log/apache2/error_log
    • /var/log/apache2/access_log
  • web路径对应的本地路径
    • http://localhost/ 对应的本地路径 /Library/WebServer/Documents/
    • http://localhost/~apc999 对应本地路径 /Users/apc999/Sites

Monday, February 17, 2014

[Emacs] Mac OS Terminal中设置Emacs热键

由于工作条件的一些限制,我不能在MacOS中之间使用单独的Emacs App而必须要在Terminal里运行Emacs.所以我花时间设置了一下我的Emacs,使的它在Terminal中也可以像在App里一样完美运行.

最大的障碍来自于Terminal里对于热键的设置


在Terminal里设置按键(单独的按键以及组合按键)所激发的xterm key code. 下面这张图是我的设置:
主要是关于方向键加上ctrl/shift/alt的组合.

关于xterm key Code:

Terminal将按键事件转换成一个xterm key code并发送给当前窗口中运行的shell. 比如Shift加上方向键up被记录成一个code "\033[1;2A". 这里"\033"其实对应的是Esc键.
关于更多的xterm key code的简介可以从这里获得:


更加完整的的关于xterm code的reference:
总而言之, 你需要把你需要用到的组合按键设置在Terminal中, 使得Emacs可以收到

剩下的就是对于Emacs里热键的设置


Emacs的key mapping系统无比的复杂. 我使用了一种笨办法: 把每一个我关心的热键组合的xterm key code都在input-decode-map里定义成对应的组合键. 比如下面的设置. 这里"\e"相当于"\033"
(define-key input-decode-map "\e[9A" [(meta up)])
(define-key input-decode-map "\e[9B" [(meta down)])
(define-key input-decode-map "\e[9C" [(meta right)])
(define-key input-decode-map "\e[9D" [(meta left)])
(define-key input-decode-map "\e[2A" [(shift up)])
(define-key input-decode-map "\e[2B" [(shift down)])
(define-key input-decode-map "\e[2C" [(shift right)])
(define-key input-decode-map "\e[2D" [(shift left)])
(define-key input-decode-map "\e[10A" [(shift meta up)])
(define-key input-decode-map "\e[10B" [(shift meta down)])
(define-key input-decode-map "\e[10C" [(shift meta right)])
(define-key input-decode-map "\e[10D" [(shift meta left)])

这样Emacs才能在key stream里识别出来传进来的meta/shift/ctrl等热键. 然后再使用Emacs里的global-set-key来绑定组合到特定的function上, 比如我设置meta加up为backward-paragraph:
(global-set-key [(meta up)] 'backward-paragraph)
(global-set-key [(meta down)] 'forward-paragraph)
(global-set-key [(meta left)] 'backward-word)
(global-set-key [(meta right)] 'forward-word)

Tuesday, February 04, 2014

[Linux/Mac] Terminal收到的Control Code和Escape Sequence Code

在Linux和Mac里使用Terminal的时候常常会出现按下一个组合键出来一堆奇怪字符的情况. 这通常是由于这个按键组合未被Terminal识别成功. 现在操作系统的Terminal通常已经足够强大, 比如MacOS自带的Terminal以及iTerm等都可以自己设置从按键组合到Control Code或者Escape Sequence Code的映射来传给Shell. 由于我常常被这个问题困扰, 所以写下这篇笔记.

何为Ctrol Code和Escape sequence code?


这里有几篇很不错的讲解Text-Terminals on Linux以及Linux Console Codes

基本这是一套沿用多年, 对按键组合编码的方案. 简单说来, Escape Sequence Code就是讲一个按键组合变成以\033(键盘上得Esc键)打头的一串字符. 比如
up     \033[A
down   \033[B
right  \033[C
left   \033[D
shift+up     \033[1;2A
shift+down   \033[1;2B
shift+right  \033[1;2C
shift+left   \033[1;2D
meta+up      \033[1;4A
meta+down    \033[1;4B
meta+right   \033[1;4C
meta+left    \033[1;4D
ctrl+up     \033[1;5A
ctrl+down   \033[1;5B
ctrl+right  \033[1;5C
ctrl+left   \033[1;5D
不难看出其中的一些个规律 (Alt: 1, Ctrl: 2, Shift: 4, ...). 更多的code可以参考: Key Codes以及 xterm code:

如何得到一个按键(或者按键组合)当前对应的Escape Sequence Code


在MacOS的terminal里可以很方便的
Keystroke to Type Expected Output (for VT220 mapping)
ctrl-V backspace ^?
ctrl-V delete ^[[3~
ctrl-V ctrl-H ^H

或者使用sed命令
$ sed -n l
在Linux的terminal下, 运行xev, 桌面角落里会出现一个小对话框。 同时terminal里会输出当前的事件, 比如按下了哪个键,松开了哪个键, 进而可以获得这些键的code


在Emacs里如何使用键映射(keymap)

这是我写的一篇笔记Mac OS Terminal中设置Emacs热键
http://blog.csdn.net/joans123/article/details/7562212
Mastering Key Bindings In Emacs

Thursday, January 02, 2014

[Linux] aptitude vs. apt-get

功能上的区别:

http://www.debian.org/doc/manuals/debian-faq/ch-pkgtools.en.html#s-aptitude

彩蛋上的区别:


$ apt-get moo
         (__) 
         (oo) 
   /------\/ 
  / |    ||   
 *  /\---/\ 
    ~~   ~~   
...."Have you mooed today?"...
$ aptitude moo
There are no Easter Eggs in this program.