Beautiful Code

<Beautiful Code>一书不算薄,里面的38位作者,也算得上个顶个的牛。但总的来说,信息量却不太大。

耐着性子看到最后一章:<Writing Programs for “The Book” by Brian Hayes>,却突然有眼前一亮的感觉。

我对Brian这个人不太熟悉,从书后的介绍中得知,Brian是<American Scientist>计算机专栏的作者。比起其他几篇文章,这篇在文字上,明显要自然流畅一些。

Brian在本书中讨论的问题,其实很简单—判断三点共线。

我们人在判断这个问题的时候,自然可以简单的进行目测。当目测不足以区分的时候,可以连接任意两点,接着看另外一点是否在那条直线上。

放到程序里,最自然的思路莫过于,过同一点计算并比较斜率。然而,诚如书中所言,计算斜率的方法有一个边界条件—平行于Y轴的直线斜率不存在。对于这些边界条件,不得不加上条件跳转去处理。更为糟糕的是,如果三个点中,有两个点都是原点,那么这三点肯定是共线的,但这两个原点的斜率,却可以为任意值。

我们注意到,很多边界条件是由坐标系带来的。因此,如果我们选择计算三个点两两之间的距离,并且比较短边长度之和与长边长度。我们可以绕过很多泥沼,代码也因此变得简洁。

然而,这样做依然存在一个固有的问题—有理数的点之间,可以有无理数的距离。这当然是计算距离时,开根号给闹的。无理数距离的问题在于,这种精度问题,并不是由问题的输入带来,而是由中间步骤产生的。

Brian最后给出Jonathan Shewchuk的方案是,计算三点所构成三角形的面积,并与0作比较。

计算面积比起计算边长的优势在于,面积可以通过同顶点两个矢量的叉乘来计算(如下图所示)从而避免了开根号。也由此把精度问题,限制于输入数据的精度。

|x1-x3 y1-y3|
|x2-x3 y2-y3|

最终代码如下(三个点分别为p, q, r):

(defun area-collinear (px py qx qy rx ry)
(= (* (- px rx) (- qy ry)) (* (- qx rx) (- py ry))))

这个例子虽然极其简单,但把它稍稍一般化,就能反映出很多问题:

大部分情况下,我们会写出类似于计算斜率的直觉算法。更糟糕的是,我们甚至可能漏掉斜率不存在,或者斜率为任意值的边界。
DEV CC之后,QA一测,发现了斜率不存在的问题,于是代码里加上一句if条件分支,注释上bug号。
Beta之后,用户complain如此明显的,原点斜率不存在的bug,大家开会聒噪一番,DEV和QA相互指责一番,于是乎又多了一句if。
ZB之后,大家怀着忐忑的心情RTM,指望CRT不要过来抱怨,用户报了一堆bug,又得加班。

于是在质量保障指引下,代码距离美丽的标准渐行渐远。直到某一天,performance真正成了问题。

牛人大笔一挥,升级算法为计算边长,更新产品名称为XXX 2009(Engine Updated)。
不久,挑剔而又无聊的客户开始抱怨精度问题,大家讨论一番,牛人决定By Design回去,并且在Readme里面的Known Issues里加上一句说明。
当时间沉淀了计算边长的代码,这段代码也就成了不朽的丰碑和牛人津津乐道的谈资。

这时候,偏有不喑世事的小屁孩说,为什么我们不计算面积呢?
牛人说,我呸…哪凉快哪待着去…

牛人就是牛人,小屁孩暂时还不明白一个道理。如果你写了计算面积的代码,你就作出了一个假定—人们都知道用叉乘来计算面积。
小屁孩以为自己的长篇注释,能够把问题说清楚。然而,忙碌的人们谁会想听你一个小屁孩的教导。
这时候,小屁孩不得不感叹思科电话设计的完美,即使你把听筒拿起来,依然能有人打爆小屁孩的电话,要他亲自,一遍又一遍的解释。

世界的完美,往往就体现在对于完美的求不得与不可求。

Embarrassed Bonus

外企死工资,年薪说多少就多少。
工作以来,因为各种各样的原因发的bonus,累计起来也只有1000多,还必须在一个网站上兑换,每次拿来也不知可以干什么,随手就捐给红十字会了。
反正自己也定了个小目标,慈善要从小做起,从工作起,每年都捐某一数目的钱,求个心安。
如果像现在这样,捐了bonus,也就不用捐太多现金了。

这次又发了1350,算是一个项目单独奖励,于是决定用掉。选了半天,除了健身、美食和旅游,稍微实在点的,就只有joyo网的礼品券了。
兑换如下:

1000 x 1
AM3851947375
23UV****
200 x 1
AM3851872516
CYJD****
50 x 3
AM3851773557
HBL5****

AM3851773429
YSPQ****

AM3851773398
ECLJ****

然后,又辛辛苦苦选了1000元的书和耳塞,还有一个加湿器,终于下了单,付款的时候,才发现一个订单只能用一张礼品券,我…
堂堂亚马逊,到了中国,沦落为卓越不说,水土不服,还做的这么烂,唉…

算了,拆成两个订单。1000元的礼品券,搞定书和耳塞,200元的礼品券,搞定加湿器。当然其间还得添一些快递费用。

最后自然剩下了三张50的礼品券。我想如果我捐礼品券给红十字会,可能会被人砍。
所以…需要的同学,联系我吧,免费奉送了。

[Updated: 派发完毕…新年快乐]

Files

唉,这年头真是没啥隐私了…

http://rc114.com/college/

查个人档案;性别、生日、年龄和学历,都可以轻松查到。

B0346096 游天 男 1984-12-15 大学毕业

有个特殊用处,就是找到同年同月同日生的人…
当然也可以找到同学校同专业的人…
当然也可以找到同名同姓的人…

Hotkey Power

一直想找到一个合适的Embeded Language,只因为厌恶tcl的语法…

这个Hotkey程序整合了几个我喜欢的脚本,并用AutoHotKey生成exe,可以直接运行。

傻瓜步骤:

1. 下载并双击运行 – 会生成一个Config.ini配置文件
2. 右键点tray icon,然后点Help看看帮助
3. 更改Config.ini文件,然后重新双击运行,加载配置

源码清单:
http://github.com/axqd/HotKeyCombination

视频教程:
http://blog.axqd.net/2009/10/17/camtasia-studio-6/

工作以来败家总结

今天看到很多人在总结过去的一年败家事项。乍一回想,工作一年多,貌似买的败家货也不少,立此存照,以此为戒…

  • Nokia 3110c – 1390
  • Nintendo DS Lite – 1400
  • Asus Eee PC 701 – 2120
  • Nokia N95 8G – 3830
  • Apple iPhone 3G – 4370
  • Yamaha Portable Grand – 1610

不过,老实说,除了Nokia N95 8G,其他都还蛮值价的 😀

What The C*nt…

其他方面不知道,但UI让我只晃了一眼,就求饶不想再看另一眼的,恐怕也非Windows 2k8 Server Core Edition莫属了。

乍看之下,像是中毒之后,explorer被cmd换掉的产物。

唉,工作了就是惨。见过烂的,没见过这么烂的…