rlwrap – 命令行下readline的封装

发现了rlwrap这个好东西。 在Mac OS和Linux下一直都用bash,bash下命令的输入都是通过readline这个库来处理的。也就是说,上下箭头查看历史命令,Ctrl+r反向查找匹配历史输入,以及Ctrl+w, Ctrl+a等等操作都是由readline提供的。rlwrap提供了readline的封装! rlwrap runs the specified command, intercepting user input in order to provide readline’s line editing, persistent history and completion. 也就是说rlwrap提供一个输入环境,在这个输入环境下可以使用readline的各种功能。如果一个程序在命令行下接受输入,那么用rlwrap直接就可以得到像在bash下输入那样的效果。 比如一个简单的反转输入行的程序 #include #include #include int main(int argc, char **argv) { using namespace std; string str; cout

在latex中调整hyphenation

用latex写英文论文的时候,可能会遇到断字符 (hyphenation) 在不该断开的地方断开的问题。因为英文单词长短不一,latex排版的时候为了让论文整体上看起来比较美观,可能会把落在行尾的单词从中断开,一部分留在当前这一行并且以一个短横线(-)也就是Hyphenation结尾,剩下的部分新起一行。 在英文文章的排版中,hyphenation是很重要的,特别是当行尾的单词很长的时候,如果不作断字,把单词都放在当前行就显得挤,新起一行就显得松。因为中文文章不存在这个问题,所以自己平时也没注意到。至于各个单词具体应该怎样断字,我还没有完全弄清楚,似乎也没有一个明确的规则,而且对于美式英语,英式英语也不尽相同。但是有一些简单考量一个断字点是不是正确的方法,比如,会不会造成歧义,是不是和单词的读音一致,或者是不是前/后缀之类的。 latex使用了处理断字的算法去自动的找断字的地方,而且latex会调整单词间距,使得文章看起来不会显得疏密不一致。大多数情况下,这些算法都工作得很好。但是因为断字的算法是根据某种规则来处理单词的断字,而不是依照人工事先标注的字典,所以,它仍然会出问题。或是在不该断的地方断开了,又或者是断开的地方太多了等等。在latex下可以通过调整参数和指定断字点来处理这些问题。 \hyphenpenalty=5000 \tolerance=1000 可以把这两个参数的调整加到tex文件里。hyphenpenalty的意思比较显而易见,这个值越大断字出现的就越少。tolerance越大,换行就会越少,也就是说,latex会把本该断开放到下一行的单词,整个儿的留在当前行。调这两个值就可以得到不一样的排版,有可能可以解决断字太多的问题。 如果遇到了断开的地方不对的情况,也可以手动来指定一个单词应该怎么断。 \hyphenation{hy-phen-a-tion} 这个命令告诉latex,hyphenation只能从标有短横线(-)的地方断开。 嗯,就是这些了。

橡皮鸭调试法

偶然在StackOverflow上看到Rubber duck debugging (wiki) 这个概念,有点儿意思,不过直译成橡皮鸭调试法好像比较弱啊。 按照wiki上的说法 传说中程序大师调试代码的时候会在桌上放上一只玩具橡皮鸭,调试的时候他会不断地,详细地,向鸭子解释自己的代码… 如果没有玩具小鸭子也可以考虑向其它东西倾诉..比如桌上的花花草草,键盘鼠标 (汗)。 好吧,正经地说这也是软件工程里的一个概念,一边阐述修改代码的意图一边做调试,就会更容易发现自己的错误。 类似的,有一种现象叫做Cone of Answers,不知道如何翻译这个词。这是一个常见的现象。你的朋友跑来问你一个问题,但是当他自己把问题说完,或者说到一半的时候就想出了答案走了,留下一脸茫然的你。是的,这个时候你就起到了那只橡皮鸭子的作用… 相似的概念还有不少,前面的wiki页面底部列出了好几个。总的来说,在你试图表述自己的想法的过程中,自然地在促使自己去整理思路,重新考虑问题。Thinking out loud 可能是一种不错的做法。

Linux Swap文件

想象一下,两个实验进程跑了两天,还有一天就跑完了,这个时候你发现如果再跑一会儿内存就要爆了…怎么办? (好惊险的感觉 XD) 好吧,其实用到的只是很基本的操作系统知识,不过还真难得用到一回。 程序面对的都是虚拟内存。64位的操作系统下,虚拟内存非常大,但是实际物理内存相对而言小得多。所以,操作系统对内存分页 (就是分成一块一块的,每一块儿叫做一页) 物理内存一旦满了,把暂时不需要的页写到硬盘里。过了一会儿程序又要访问被写到硬盘里的那部分内容,操作系统就在物理内存中选一个页 (怎么选很讲究的),把硬盘里的那个给换回来。程序不停的运行,操作系统就换来换去… 所以,上面我们遇到的情形就可以解决了。把其中一个进程挂起 (suspend),Linux下可以用 Ctrl+Z ,然后这部分内存就是暂时不用的了。这个时候用 $top 查看内存使用情况,可以看到一个CPU占用率为0的进程占用的内存越来越少,另一个越来越多。这样就行了,等一个进程跑完,再用 $fg 命令把挂起的进程调到前台就可以了。 但是等等。虚拟内存具体是在哪里呢?数据终究是写在内存/硬盘上的,Linux下被换到硬盘上的内存在Swap分区 (交换分区) 里。安装系统的时候需要格式化一个分区为Swap格式,就是这个分区。 用 $swapon -s 可以查看交换分区的大小。 糟糕!刚才那个被挂起的进程占用了24G的内存,但是现在看到我的交换分区只用12G,怎么办?一旦交换分区和内存都满了,会发生神马事情,我也没有体验过,估计应该是系统卡死或者卡而不死吧。 所以,应该赶紧增加交换分区的大小才是。可是如果你和我一样,很悲催的没有Root权限 (Root权限貌似是必须的…),而且也根本没有多余的分区可以挂载了,怎么办? 可以用Swap文件 (点题) ! 就是把一个文件用做swap分区,Linux下什么都是文件,分区应该也是吧。要增加系统可用的虚拟内存,当然这要求你硬盘剩余空间够大… $dd if=/dev/zero of=~/swapfile bs=1024 count=41943040 会在HOME下创建一个40G的文件”~/swapfile”,命令要执行一会儿,需要写一段时间硬盘,执行完了会显示写硬盘的速度,可以用来做测速的。 然后告诉系统用这个文件做交换文件 mkswap ~/swapfile 就没问题了。 (实际上不行,还需要这个命令, –!) sudo swapon ~/swapfile 其实最一开始那个情形下,如果两个进程继续跑下去,操作系统仍然会把一部分内容换出来的。只是大量换页操作会让程序执行的时间更长,而且如果交换空间不够大,系统最终仍然可能会被卡死。 感叹一下,一个实验要跑三天的同学伤不起啊..

利用摄像头判断手机移动方向[MPMotionPattern]

这部分代码是做原型用的,现在已经不在项目里。 也没有什么特别的算法,所以就放在这里吧。 https://github.com/pppoe/MPMotionPattern 需要用到之前的“iOS逐帧处理录像-MPVideoProcessor”。 主要的算法是从TinyMotion这个项目来的,用到的也是他们的算法。 功能很简单,就是通过iPhone摄像头拍摄的图像,判断手机当前的移动方向。 现在也只是支持上下左右。因为iPhone本身就有传感器可以取到这种动作,所以用图像似乎也没有什么特别的优势… 只是感觉挺好玩的。XD

libstdc++ 4.6 type_traits 的一个bug

如果你的编译环境和我一样,然后又在用C++11的时候,不小心直接或者间接用到了<chrono>这个头文件,应该就会遇到这个bug。 完整的错误信息如下: || In file included from /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../include/c++/4.6/thread:37: /usr/include/c++/4.6/chrono|240 col 10| error: cannot cast from lvalue of type ‘const long’ to rvalue reference type ‘rep’ (aka ‘long &&’); types are not compatible || : __r(static_cast(__rep)) { } || ^~~~~~~~~~~~~~~~~~~~~~~ /usr/include/c++/4.6/chrono|128 col 13| note: in instantiation of function template specialization ‘std::chrono::duration >::duration’ requested here || return […]

iOS逐帧处理录像-MPVideoProcessor

一般在iOS上做录像都可以直接使用UIImagePickerController。 但有时候难免需要做逐帧的处理,比如实时的滤镜之类的。 参照这个帖子: A (quasi-) real-time video processing on iOS 把使用AVFoundation做录像的代码,做了一个简单的封装。 Delegate可以得到逐帧的彩色或者灰度图,然后就可以加上自己需要的处理了。 代码放在Gihub上:MPVideoProcessor 具体使用请参见Github上的Readme.