Lua协程实现Fibonacci算法

image

费波拉且数的算法如图所示:

image

所以a和b分别保存了前两次的结果,每次for循环调用generator都从yield这一行代码恢复然后进行a, b = b, a+b操作。然后判断a是否小于等于n决定返回结果。

如果不用coroutine.wrap,我们可以这样写,效果是一样的,代码稍显啰嗦:

image

秀秀最近一些胶片

奥林巴斯Mju2配合Fuji100胶片,这卷拍了很长时间,但是片子质量还是比较给力滴。

最喜欢这张,每天必须的活动:爷爷带着孙女在楼下玩。

Happy的母女俩。

去朋友婚礼我喜欢带着这个小相机,不担心弱光或者没电的情况。

大连Python用户组活动简记

在王元毅(@yuanyi_wang)孜孜不倦的努力以及大连天维科技李丕总经理的大力赞助支持下,大连Python用户组终于在一个大雨滂沱的早晨成立了!

大连这几天都是湿漉漉的,动辄就是下雨刮风。我从家里出来的时候还没有下雨,结果车坐到一半就开始大雨瓢泼,等到下车的时候,车站路边积了很深的水,只有趟着过才行。

天维科技就在七贤岭车站边上的高层办公楼,16楼。我去的时候还不到九点(约定开会时间九点半),这一带高楼大厦那是多多,可就是没有买吃的地方,与其等着不如去买点吃的,就跑到黑石礁买了麦当劳早餐。结果雨越下越大,再回到天维科技办公楼的时候已经是九点五十,会议室里已经坐了不少朋友,扫一眼大概有八九个人。

大家闲聊了一阵,然后元毅主持会议开始,首先是各自做自我介绍,除了twitter上的ouland、gamtin,其他朋友不是很熟悉。除了天维的李总,基本上都是搞程序开发的,还有几位朋友是做测试方面的工作。

介绍完了各自情况,元毅做了一个对Python的简单介绍。然后我做了一个Lua的简单介绍以及代码简介。

大家除了讨论Python的相关问题,也对天维公司www.5itvi.com非常感兴趣,我在李总作介绍的时候问了不少问题,主要是对他在贝尔实验室的经历非常感兴趣,要知道贝尔实验室那是牛人多多啊。

最后李总给我们演示了天维媒体中心这个产品。这里要着重提一下,天维这个产品有些类似盛大以前的盒子,可以非常高效使用高速宽带,实现游戏、视频点播、高清播放甚至网络电话的这样一个平台。由于不知道产品细节适不适合在这里细说,就不多说我看到的演示过程,但是可以说这个产品是非常有意思的,就我个人而言,对其中网络电话这部分很感兴趣,遥控器可以作为网络电话的话筒。用一句话来说就是:我很有对这个产品的购买欲望。天维这个产品的界面以及服务器部分使用Python完成,就我所知是大连地区唯一一个使用Python做产品的公司。

整个活动其实还是比较简单,没有其他地区用户组活动比较深入的讨论,这是很遗憾的事情,但是比较符合大连整个软件产业的现状。尽管官方大力吹捧大连是所谓的软件产业为主,个人觉得这里面水分太多,所谓的软件开发大部分是日韩或者欧美的外包业务,少有核心研发业务,而且官方几乎也没有组织过什么软件开发方面的论坛或者研讨会。唯一参加过的就是微软在大连的广告宣传(而且也挺水的)。我在讨论中也稍微有些激动的提到,对大连成立Python用户组那是期待已久,其实讨论Python也好,研究DotNet或者Java也罢,Topic是一部分,最重要的是大家有这样一个平台可以线下互相交流。Python大连用户组的成立填补了我这个遗憾,即使现在大家还没有什么深入的内容讨论,也许将来讨论的也未必高深到哪里,但是我真的很爱这种可以跟其他喜欢技术的朋友交流的感觉。

C语言中的表达式求值问题

在细读《C programming Language 2nd》(K&R)到53页的时候,看到作者举了这样一个例子:

a[i] = i++;

如果你知道这个表达式有什么问题,就不需要继续看下去了,下面内容对你而言有些浅显。

如果你也像我一样,觉得这个很容易理解啊,i++这个表达式就是先取i的值返回,然后对i自加。a[i]就是i的值,然后i自加1。

这其实也是C语言陷阱之一,在K&R中反复强调(page52以及page202),函数参数也好、某个操作符中的操作数也罢,表达式求值次序是不一定的,每个特定机器、操作系统、编译器都不一样。(特例是&&,||,?:以及逗号操作符,它们会确定表达式求值顺序的)

还有类似的例子如下:

f() + (g() * h())

或者 int i = 7;  printf("%d\n", i++ * i++);

在我们一开始提出的问题中,a[i]取下标操作与i++自增的运算顺序是不一定的。这就是一种不确定性。

在第一个表达式中,可以确定的是这些内容:g和h函数的结果会先做乘法运算,然后与f函数的结果做加法运算,但是f,g,h谁先被调用,谁后被调用,这是不一定的,C语言标准没有对此作规定。

第二个表达式中,第一个自增操作和第二个自增操作以及乘法操作的顺序是不一定的,所以结果根本无法确定,即使我们给i++都包裹上括号 (i++) * (i++)也是一样的。括号并不会得到确定的操作数计算顺序,括号只能保证操作数的值(就是表达式或者函数求值的结果)相互计算的顺序。

K&R提供了几个建议,首先是函数调用嵌套赋值语句(或者可能改变参数值的操作)或者自增操作,都会有"side effect”,我们应该确保这种边际效应不会影响程序运行结果,如果某个表达式对同一个变量同时修改两次,那么一定要非常注意这是不是你想得到的结果。

如果不知道特定机器上实现如何,就不要依赖表达式计算顺序;即使知道了实现方式,这种依赖也不是一种好的编程方式。比如f、g、h函数计算,可以用赋值给临时变量来决定需要的顺序,对于print(i++)这个表达式也是如此,在printf之外先计算i的值。用K&R第一版的话来说就是if you don’t know how they are done on various machines, that innocence may help to protect you.

参考资料:

http://www.eskimo.com/~scs/cclass/notes/sx7c.html

《C Programming Language second edition》