Fermat618's Blog

Happy coding

重新弄好打印机的经过

Linux 系统下一直能用的打印机,大概又是因为升级,从前一段时间开始,就不能用了。显示打印成功,但是打印机绝不动一下。删除后重新安装打印机,一切都显示正常。都显示正常,没半点报错信息。

终于忍不了了,折腾了老半天,算是搞定了。

首先,安装 hplip 这个包,为了不出问题,我顺带连 hplip-gui 也一起装了。

再以 root 权限运行 hp-setup 命令。

以上过程,每一个都不能错半点,否则你也得不到半点错误提示,甚至会得到正确提示,但打印机就是不能用。

比如说,在系统的打印机管理里面添加打印机,不管你怎么弄,打印机都成功不了。或者运行 hp-setup 命令时没有用 root 用户,那么会在后面的一个步骤上卡死,那个界面你再不无法点得动了,打印机自然也是安装不上的 。

又写了个油猴脚本

来个总结吧。

首先,是如何看到脚本出错信息。脚本出错的信息,只有在全浏览器的控制台下面,才可以看到。按 Ctrl + Shirt + J, 可以进入浏览器的控制台。在过滤窗口,输入脚本的名字的一部分,可以过滤出错信息。网页上的 javascript, 普通写得烂,出错信息一堆堆的,不过滤 ,有用的信息就会被淹没。

临时调试脚本,可以使用 Firefox 自带的代码片段速记器(shift + F4)。按 Ctrl + / 可以方便地注释掉一行。想知道某些东西有哪些方法可以调用,可以选中那个对象(或返回一个对象的表达式),按查看,就可以看到。

Firefox 自带的开发者工具的好用程度,已经超出了 firebug, 所以不推荐用firebug 了。

如何存储信息。使用 GM_getValue, GM_setValue, GM_deleteValue, GM_listValues 等函数,可以针对每个脚本存储本地信息。由于单个的 GM_setValue 不可以存储列表,我把整个存储空间当成一个列表来使用了,反正我与个脚本也只需要存储一个列表。要再加功能,另开一个脚本就好了。

写稍复杂点的功能时,使用 typescript 比直接使用 javascript 爽多了。特别是想建立类的时候,代码干净了很多。

最后,说一下我写的这个脚本的功能。上论坛时,总会遇到某些令人不愉快的人,而很多地方又没有提供黑名单功能。为了屏蔽掉这些人的帖子,我以前写了一个脚本,把这些人的名字保存起来,然后过滤掉这些人发的帖子。但是那些个名字都是以字面形式保存在代码里面的,每次需要把人加入时,就要手动打开程序,编辑文本,很是麻烦。所以,这回我把代码改了一下,直接点击鼠标就可以把某些人加入到黑名单里面。

双显示器的连接

长久以来,多次感觉到,文档与编程窗口不能同时看见,经常需要切换,影响效率。看到有人说到,双显示器可以大大提高程序猿的工作效率。正好旁边又有一个显示器,于是便想拿来用了。

首先遇到的一个问题,便是没有两个 VGA 接口。主机是 Intel 集成显卡,机箱倒过来一看,有一个 VGA 接口,一个 DVI 接口,另一个 HDMI 接口。便想到了接口转换,问了下其它人,只要是把显示器插上去了,就可以。上网找相关的转换线,有 HDMI 转 VGA 的,也有 HDMI 转 DVI 的, 但 DVI 转 VGA 的,只有 24+5 转 VGA 这一种类型,没有 24 +1 转 VGA 的。双上网查询 DVI 接口相关资料,恍然大悟,DVI 分 模拟 (DVI-A)、数字(DVI-D) 和集成(DVI-I) 三类,而 X+5 与 X+1 相差的那四根线,正是用来传递模拟信号的。于是死了心,DVI-D 转 VGA 的转接口,看来是没有了。

转换线拿到后,把显示器插上,果然,双显示器立即就可用了。在 Gnome3 的“显示”设置上,还可以调整两个显示器的相对位置。默认的是把主显示器在左边,后来插上去的,也就是第二显示器,在右边,刚好符合。

工作了一段时间后,遇到另一个问题,便是 pycharm 的弹出菜单总是出现在第一块屏幕上面。上网查询相关的信息,发现这是早就存在的一个 Bug. 查询多个帖子,有说把 JDK 从 1.7 降到 1.6 的,把 X 的模式换成 Xinerama 的,还有 Ubuntu 下特定的,把启动快捷菜单的 autohide 设置成 on. 最后一个 Ubuntu 特定,是不能用了。X 模式也不太明白,也没看到有人说用这种方式成功的。倒是看到了不少把 JDK 降级而成功解决了这个问题的,但没说具体方法。是于,自己用编辑器打开 pychar 的启动文件,查看相关代码,终于找到了 PYCHARM_JDK 这么一个环境变量,而且后面在检查 $PYCHARM/bin/java, 于是,这个变量应该设置成什么样子,也就知道了。试着命令行中用

PYCHARM_JDK=/usr/lib/jvm/java-6-openjdk-amd64 charm

启动,果然,Bug 不见了。


最后,把 pycharm 安装目录下 bin/pycharm.sh 中,加上了这一句,以免每次都需要手动打。

Vim 的超级牛力--一次 debug 经历

Python 在数值计算方面,有一个非常好的功能,可以写一个 Fortran 程序,然后通过简单的 f2py 命令,便可变成一个 python 模块,以供在 python 里面调用。

 

在我用 f2py 把 Fortran 文件编译成 python 模块时,遇到一个奇怪的问题。当用其它的编辑器打开并修改  .f90 文件后,再使用 f2py 转到 python 模块,会发现模块里面的变量值没有更新。但当使用 vim 打开文件并保存后,就能得到正确的值。

 

刚开始,我以为是不同编辑器对修改时间可能有不同处理,影响到构建程序依赖关系得不到正确处理。所以,我改用了直接调用相关命令,而不依赖于 scons 的自动构建。但是,问题依然存在。

然后,我 又试了不同的编辑器,eclipse 的内置编辑器,nano, gedit, emacs 等,其它编辑器表现一至,除了 vim 比较特殊。

 

这个没办法了,我又拿出其查看访问时间与修改时间的东西,当编辑器保存完时,查看这两个时间,没发现 vim 和 其它编辑器有什么不同。

 

后来,我新建了个目录,把相关的文件放进去,终于发现,当有 .mod 文件存在时, f2py 会用原来的 .mod 文件,而不是生成新的 .mod 文件。

 

为什么 .mod文件能影响到 python 中 module 变量 的值呢,是因为我用了带 parameter 的变量,这样的参数会被写入到 .mod 文件,而不是 .o 文件。

 

后来的后来,我发现用 vim 修改了文件之后,python 模块中的变量值,变成了一个乱码。于是我又保存了老的 .mod 文件,再跟用 .vim 保存完 .f90 后的 .mod 文件相对比,果然,内容变了。

再仔细一看变了一部分,real 默认成了 real 8. 我喜欢用 -fdefault-real-8 来写 Fortran 程序,这样子,不用每次都写 real(8) 了,省事得多。这个参数需要手动指定,我在哪里指定了这个参数呢,SConstruct 中,但是那个文件不在当前目录,起不了作用。

终于的终于,我想起来了,在 vim 的插件 syntastic 的配置文件中,我指定了这个参数。由此,一切直相大白。synntastic 会在保存的时候,编译一遍当前文件,相获得语法错误,于是,就产生了新的 .mod 文件。

 

f2py 在这个地方没有问题么,也有。问题在于,它隐式的采用了一个中间文件,而没有任何的警告。这是不妥的,如果要采用那个文件,要么使用显式的命令行参数来指定,要么另外生成。就像在运行 gcc main.c foo.c 时,无论有没有 main.o 或 foo.o 存在,编译器都要新生成一个 .o, 因为命令行参数中指定的,不是 .o, 而是 .c.

gfortran 新坑: 未初始化的变量不会给警告

每当遇到些意外的时候,也就是初坑了的时候,我就要写篇日志了。

这两天模拟一篇 PRL 上文章,结果一直不对。我一直以为是随机模拟的数据错了,最后用了一个很笨的办法,看出来,原来是理论曲线算错了。

这实在是一个很奇怪的事情,因为算理论曲线的那个程序,相当清晰,而且是在我加了 -Wall 参数编译以后,没有任何警告就通过了。程序运行起来也没有任何的问题,但是结果不对。

只好拿着代码,一行一行慢慢看,寻找每一个变量的来源,与公式进行对照。忽然间,发现一个参数定义了,但是没有初始化。这頗为让我惊讶。如果一个变量声明了,没有使用,会有一个警告的。但变量声明了,没有定义而使用了,竟然半点警告也没有。

我记不清Fortran标准里面有没有规定一个变量如果没有初始化,哪种情况下会被初始化为 0。在 C 语言里面,函数里面的自动变量(main也是函数), 如果没有初始化,值会是随机的,不管是教科书,还是编译器,都给了警告。gfortran 竟然不会给警告,真是难以让人相信。

我继续查看 gfortran 的文档,想开启更多的检查开关,结果发现了如下一些项。


-ffpe-trap=invalid,zero,overflow,underflow,denormal


开启浮点数异常的检查,以及

-finit-real=snan

来把real型变量初始化为 snan. snan 是在开了检查之后会报错的 Nan.

再说一下标题栏

今天忽然想到,把 Firefox 的在量大化的时候,隐藏掉,这样能节省不少空间。于是上网找插件,又想起 gnome3 的文档查看器在最大化时隐藏标题栏的效果,最终找到了实现这种效果的插件。

标题栏的作用有如下几个

  1. 显示文档标题
  2. 提供鼠标点击拖动的地方
  3. 显示「最小化」「最大化」「关闭」这几个窗口管理的按钮

其中第2、3功能,对于最大化窗口的管理,比较的重要。要方便地进行这些窗口管理操作,就需要标题栏厚一点,这样点击的难度会小一点。

然后标题栏过厚,会引起一个问题,占用过多的空间。特别是对于PDF查看,网页查看,上下多一些空间,意义比较大。

于是一些浏览器开始自绘标题栏,把标题栏弄得窄窄的,并且把菜单或标签页也放到标题栏上面。这一来使得点击拖动窗口变得不方便,二来自绘的窗口往往显得跟系统的其它窗口格格不入,很不协调。

Gnome文档查看器(在Gnome-shell中)对窗口标题栏的管理,是我见到的最聪明的做法。它在非最大化的时候,让系统绘制一个比较厚的标题栏,而在最大化时,隐藏标题栏。点击黑长直的空白区域往下拖动,可以使窗口从最大化状态恢复到普通状态。窗口最大化时,标题栏的功能大多减弱 。比如,窗口移动就不需要了,又不需要区分不同的窗口,显示标题信息也没那么重要。此时,标题栏显得更加的碍事,而不是有作用。所以这种做法是比较合适的。

Firefox 的 HTitle 插件,准确地实现了上面的功能。而另一个插件,功能花哨,还自绘标题栏,很是没用。

Firefox 29 的界面又进步了

今天 Firefox 提示自动更新了,更新完重启之后,出现一个向导,介绍 Firefox 29 的新功能,我跟着步骤,一步步看完。

Firefox 改进的第一点,是收藏夹按钮变了。以前只有一个五角星按钮,现在是左边五角星,右边是收藏夹,两个按钮绑定在一块儿。试着点了一下左边的五角星按钮,差点喷了一口水。五角星很Q地跳了出来,跳到了右边的收藏夹图标里面。点击收藏夹,会出来一个下拉菜单,可以选择或管理收藏的网址。

第二点是右侧的菜单栏,点击后,菜单栏会弹出来。这个新菜单栏与以往的菜单栏有较大不同,首先是所有选择项都是方块,每行有三列,且上面距离也大,可点击区域大,要准确点击的容易程度大大增加。然后,这个菜单的内容是完全可定制的,定制的方式是随意将图标在工具栏,左侧图标库及菜单栏之间拖放。

第三是标签的视觉效果更好,更能明显地看到当前的标签是对应标签页上的哪一个。

再说一点,Firefox 界面简洁好看,又不突兀,与整个系统的协调感很好。特别是用上了 HTitle 插件后,在最大化时可以隐藏掉标题栏,更舒服了。不像某些连标题栏都是自绘的程序,看着太不协调。

而带来的不便,也是有的。最明显的一点,是底部的「附加组件工具栏」没有了。把自己常用附加组件的功能,放到标签栏与菜单里面后,也可以满意。再加上按 Alt时,菜单栏会自动出来,用完自动隐慝,可以缓解解决需要的时候找不到按钮的问题。

滚动条的一个小细节

滚动窗口右侧的拖动条,这个应该不陌生。既可以表示进度,又可以用于定位。然而,当我把 gvim 最大化时,鼠标也移动到最右侧边框,点击,竟然没有触发滚动条。

之后,又试了一下其它的程序。Gnome终端,文件管理器,图像查看器,以及火狐,都没有问题;但 gvim, emacs, pidgin 就不灵。大致看了一下,就是新的,GTK3 的软件,一般没什么问题;老的,GTK2 的软件,就往往有问题。可见升级还是有作用的。

在右侧滚动条上,我见过做得最好的软件,是 jetbrains 的 intellij idea(或 pycharm). 不但没有上面的问题,还用各种颜色表示出分析代码所得到的有用信息,点击相应的位置,就可以迅速跳到源文件中相关的地方;而把鼠标悬停在上面,就可以看到信息的具体内容。这软件的 UI, 真是到了相当高的水准!

Gtk Tree View 子节点乱跑的问题

pida 有个 ctags 插件,可以从 ctags 分析出来的文件中,新建 tags. 但有时,会发现 tags 乱跑的问题,即某一个父节点的子节点,跑到其它地方去了。

ctags 输出的文件,在程序内部,经分析后,成一个一个的元素。每一个元素,有一个指向父节点的指针。在把这些分立的节点插入进 tree view 的时候,如果子节点先插入,插入时其父节点还未被插入,那么,那些父节点在插入后,不会自动把以前的子节点收进来。

解决这个问题的一个办法,是在插入 tree view 之前,先调整顺序,把一个节点的所有父节点,都放在自身的前面。因为节点可以有分级,父有子,子有孙,递归和 Python 的生成器恰好派上用场,程序看起来就很简洁明了了。

        items = list(....)

        def pop_parent_first(item):
            p = item.parent
            if p is not None and p in items:
                for i in pop_parent_first(p):
                    yield i
            else:
                items.remove(item)
                yield item
        while len(items) != 0:
            item = items[0]
            for x in pop_parent_first(item):
                yield x

第一行,是把原来的元素,做成一个列表。pop_parent_first(item) 函数,在弹出一个对象前,检查有没有父对象,如果有,延后自身弹出,先把它的父对象弹出来。

在 anjuta 中,我又发现了这个问题,觉得很可能是上面这个原因。可惜的是 anjuta 用 C 写的(而不是vala),难找到有用的信息,看了一会,也没找到出错点。

一句话说说机械键盘

以前我每天有大量的时间使用电脑,而且键盘敲击比较多,所以很快便关注到机械键盘。

在没有机械键盘的时候,我在网上读了很多的文章,各种云里雾里的描述,使用感受,曲线对比,看得眼花瞭乱。但第一次买的时候,毕竟是花几百块钱买个键盘啊,慎重,慎重。于是,看了一篇又一篇的吹得天花乱坠的文章。

等买到手,才发现,事情比想象的简单多了。那么多的文章,没一篇写到了我最关心的问题。

机械键盘的本质是什么?是弹簧。

而弹簧,是我们大家都熟悉的东西。按动型圆珠笔,里面就有一根弹簧嘛。按一根弹簧的感觉,就是越按受力较缓慢,呈现性地增大。所以,弹簧制成的键,最明显的特点,就是“回弹有力”。

薄膜键盘,提供键盘被按下后弹起的力的装置,是硅胶碗。这种结构,导致了其受力会在胶碗未塌陷时,达到最大,而塌陷后,回弹力迅速失去,整个按键撞到底部的硬板,才能停下来。

由于材料特点,薄膜键盘硅胶碗的老化速度,比起金属材料的弹簧,要快得多。所以,机械键盘的好手感,能一直保持,而薄膜键盘不行。

对待机械键盘的态度,我其它没有多少猎奇心。我想要的,只是找一个更加舒服更加稳定的日用品。然而,以这种态度写的关于机械键盘的文章,几乎碰不到。大概是这类用户少,并且写文章的可能性要明显低的原因轻。

也正是因为这个原因,我喜欢茶轴键盘,这是一个被猎奇用户看不起的一类机械键盘,而很多人不喜欢的原因,一是「特点不够明显」,二是「跟薄膜键盘比较像」。说茶轴跟「薄膜键盘比较像」的人,有一个重大的描述错误。由于结构特点,茶轴怎么着也是「跟机械键盘比较像」的。而他们所推崇的黑轴,红轴,不过就是跟光光的弹簧。相比较,茶轴,是加了点「确认感」的弹簧。那就是,当按下一个键时,到达一定的位置,会感觉到一点反馈,告诉你,你按的这个键已经生效了。对于我来说,这一点是比较重要的,因为这一点,用起来有安心的感觉。