番外之三:极客男友的情人节礼物大作战

最后更新于:2022-04-01 02:40:35

> 是时候应该反击了 当我看到[@鄢得諼草](http://www.weibo.com/hug8217) 的那几篇黑我黑到体无完肤的#极客爱情# @Phodal 故事的时候,我发现我竟无言以对。或许,作为一名程序员,我们或多或少都有这样的共性。 * [技术宅不解风情](http://www.xuntayizhan.com/person/ji-ke-ai-qing-zhi-shi-ji-shu-zhai-bu-jie-feng-qing/) * [和不会聊天的人谈恋爱](http://www.xuntayizhan.com/person/ji-ke-ai-qing-zhi-shi-yi-he-bu-hui-liao-tian-de-ren-tan-lian-ai/) 难道就这么坐以待毙吗?当然,决不。在即将来到的情人节之际,我准备奋起反击。 对于向往浪漫的女孩来说,亲手制作的礼物总是更能抓住女孩的少女心。不过,代码除外,除非你的另一半也是一个程序员,能轻轻松松理解深意: ~~~ while(propose.times < 99) { huahua.listen(phodal.ask("will")("you")("marry")("me")); huahua.reply.propose (); } huahua.propose("Yes"); var ever = phodal.love(huahua) && huahua.love(phodal); for(ever){;;;}; ~~~ ——至于像花花这样虽然学中文出身但是长期在我身边耳濡目染的孩子,大致能理解如此简单的表达吧。 而对于我这样一名极客来说,不是出自自己的亲手制作,总显得有那么几分的没有成就感。 到目前为止,我需要营造一个浪漫的环境,准备一份恰当好处的礼物。故而总结如下: * 自己编成的代码 * 营造浪漫的环境 * 亲手制作的礼物 `注意`: 请将下面的`《程序员的情人节礼物》`换成xx语言。 # 《[程序员的情人节礼物](http://www.xuntayizhan.com/person/geeks-love-programmer-gift-guide/)》是怎样炼成的 网页Demo: [http://valentine.phodal.com/](http://valentine.phodal.com/) 我想起她曾经满怀着羡慕的给我看知乎上的一个答案:“一个程序员给他女友写了一个程序,整个太阳系都是他和他女友的照片,太阳系的中心是他心中女友最美的照片,周围是他的照片围绕着她转,背景音乐是男主唱的《爱转角》。点开屏幕上他们名字的缩写,还有男主对他女友说的一段话。”她用她那双虽然小但炯炯有神咄咄逼人的眼睛盯着我,一副我不给她也做一个她就要宰了我的模样。 “嗯,这个不难啊,不过我是不会给你做的。” 你觉得我会让你有嘚瑟的资本吗~ (会) 所以,我想要做成的效果类似与一个能滚动展示图片的App,上面是我们相遇相知的历程,或许还需要加上音乐、照片,等等。除了下面准备的材料之外,我还需要有: * 那些我想说的话 * 她美丽动人的画 在使用类似于下面的照片时,请提前做好心理准备。 ![document/2015-08-21/55d6d47abb959](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/document_2015-08-21_55d6d47abb959.png) 我仿佛看到她怒发冲冠的模样,哈哈哈。 言归正传: ## 《程序员的情人节礼物》入门之材料构思 ### 情人节礼物之设备展示 想着在这个移动盛行的时代,再用电脑就不太合适了。要是做移动应用的话,那么手机或许可以和硬件结合地更加和谐。 找到了自己所有的移动设备,如图所示: ![document/2015-08-21/55d6d46943a57](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/document_2015-08-21_55d6d46943a57.png) 作为一个诺基亚的粉丝,从那一刻起,我不喜欢Microsoft。 * Nokia N72 * Nokia E66 * Nokia Lumia 920 * Nokia Lumia 1020(ps:拿在手上拍照) * Kindle 想想,还是放弃了做移动App的想法——没有Andorid手机,没有iPhone,没有Win 8 + VS(ps:公司的电脑不能装盗版软件...)。 好在我们有Web。 ### 情人节礼物之硬件设备 翻箱倒柜之下找到了下面的材料: ![document/2015-08-21/55d6d45b0a693](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/document_2015-08-21_55d6d45b0a693.png) 排除了一些老旧的设备: * 51单片机: 用这东西我真的可以按时交付软件么? * STM32: Mac OS下支持得不是很好。 * PcDuino: 不合适,我对它的印象是有点不稳定。 最后挑出了`Raspberry Pi` + `Arduino`,这对永恒的组合。 * Raspberry Pi当服务器 * Arduino控制硬件。 ### 情人节礼物之被控设备 想了想我们需要营造一个浪漫的环境,于是找到了这个`星空投影仪`,还有其他(ps:暂时还是需要保持一些神秘性的)。 ![document/2015-08-21/55d6d44235572](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/document_2015-08-21_55d6d44235572.png) 应该是够用的,当然还需要有其他模块: * 红外模块(ps:用处保密ing。) * 继电器(ps:用于控制星空投影仪。) ## 《程序员的情人节礼物》之美 因为我是`以编程养活自己,以写代码满足自己`的极客一枚,我需要程序来控制我们的硬件设备。 ### 框架选择 关于后台,先想到的两个语言是`JavaScript`和`Python`,Raspberry Pi的最大优势语言就是Python了,出现JavaScript的原因是我们可以统一前后台。虽然[Raspberry Pi安装Nodejs](http://www.phodal.com/blog/raspberry-pi-pcduino-install-nodejs/)也是挺简单的,然而还是觉得用Python吧。 对比了一下Python的框架,选择了轻量级的`flask`。 至于后台,之前喜欢的方案是用`jQuery` + `BackBone` + `Mustache`来构建移动CMS(ps: Github见[https://github.com/phodal/moqi.mobi](https://github.com/phodal/moqi.mobi)),在这之前的一个时期觉得他们会导致代码多了一个大小级。接着,写了自己的JS框架——Lettuce,总觉得有点过。不过,刚好够用,作为~6kb大小的框架,包含: * Router * Promise * Event * Template * Effect (小广告:如果你有兴趣的话可以试试[https://github.com/phodal/lettuce](https://github.com/phodal/lettuce),也可以加入我们.....) 也要有PySerial来控制串口。 最后我们的方案就是`Flask` + [`Lettuce`](http://lettuce.phodal.com/) + `PySerial`。 ### 思路 过程大致如下: * 网页会在展示文字 + 图片的时候自动跳转 * 网页在需要硬件执行设备的时候,会post一个指令。 * Raspberry Pi在接到指令的时候,由串口发送给Arduino * Arduino再进行具体的操作。 ## 《程序员的情人节礼物》CookBook 上面的xx语言都是瞎扯,你真正需要认真关心的是这本书。 此处省略一百字: ![document/2015-08-21/55d6d401e00c2](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/document_2015-08-21_55d6d401e00c2.png) **没有这个,那就不浪漫了。** **既然不浪漫,也没办法发朋友圈了。** **既然没有办法发朋友圈,就不能愉快地做朋友了。** (ps:大多时候,一个女孩子可能并不在意你送的礼物是什么,她要的是一份心意,以及一份可以晒的心情) ## 《程序员的情人节礼物》实战 ### Server端 为了方便起见,只好尽可能地简化代码,因为简单我也可以列出所有的代码: ~~~ import json import time from flask import Flask, request from flask_restful import Resource, Api import serial ser = serial.Serial("/dev/ttyACM0", 9600) app = Flask(__name__, static_url_path='') app.secret_key = 'why would I tell you my secret key?' api = Api(app) tasks = {} @app.route('/') def root(): return app.send_static_file('index.html') class Task(Resource): @staticmethod def post(task_id): tasks[task_id] = request.data ser.write(request.data) time.sleep(6) return tasks[task_id], 201, {'Access-Control-Allow-Origin': '*'} api.add_resource(Task, '/<string:task_id>') if __name__ == '__main__': app.run(host='0.0.0.0', port=5000, debug=True) ~~~ 在某些地方上有区别的应该就是 ~~~ ser = serial.Serial("/dev/ttyACM0", 9600) ~~~ 对于不同的平台来说,`/dev/ttyACM0`可能是不一样的。我所做的就是将收到的信息直接发给Arduino。 ### Arduino端 代码也比较简单有木有: ~~~ #include <IRremote.h> int starPort = 12; IRsend irsend; int fullStar = 1; int irRemote = 2; void setup() { Serial.begin(9600); pinMode(starPort, OUTPUT); } int serialData; void loop() { String inString = ""; while (Serial.available()> 0) { int inChar = Serial.read(); if (isDigit(inChar)) { inString += (char)inChar; } serialData=inString.toInt(); Serial.print(serialData); } if(serialData == fullStar){ digitalWrite(starPort, HIGH); } else if( serialData == irRemote){ irsend.sendNEC(0xFF906F,32); delay(1000); } } ~~~ 不断地从串口接收数据,如果为1就点亮所有的star,如果而2就发送红外。当然,你也可以拿Raspberry Pi做这些事。 ### 前台 详细代码可以见: [https://github.com/phodal/valentine/blob/master/static/js/app.js](https://github.com/phodal/valentine/blob/master/static/js/app.js),这里简单说一下基本的逻辑。 一个简单的页面代码如下所示: ~~~ var L = new lettuce(); var data = { rise: "一起看日出", down: "一起看日落", yours: "有一天,你出现了", together: "然后", rose: "IOU" }; var rise = function () { var html = '<div class="rise"><h3>{%=o.rise%}</h3></div>'; var result = L.Template.tmpl(html, data); document.getElementById("results").innerHTML = result; }; rise(); ~~~ 一个post请求,给请求发送给Arduino: ~~~ var L = new lettuce(), irRemote = "2", fullStar = "1"; lettuce.post("/serial", fullStar); ~~~ 一个Event,用于展示最后的心形: ~~~ L.Event.on("showLove", showLove); L.Event.trigger("showLove"); ~~~ Promise与SetTimeout一起来实现页面跳转: ~~~ function show(func, n){ var p = new L.Promise(); var code = function () { if (func !== undefined) { func(); L.FX.fadeIn(document.getElementById('results'), { duration: 3000, complete: function () { } }); } p.done(null, n); }; setTimeout(code, n); return p; } show(undefined, 3000).then( function() { return show(rise, 0) } ).then( function() { return show(down, 3000) } ) ~~~ ### 硬件连接图 硬件连接图如下所示: ![document/2015-08-21/55d6d3e2609f3](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/document_2015-08-21_55d6d3e2609f3.png) 需要注意的有: * 用绝缘胶带把硬件上的各种Led灯遮住 * 确保能启动。 **注意用电安全**,如果你想用于控制强电,最好找一些有质量保证的设备。 ## 其他 网页版Demo: [http://valentine.phodal.com/](http://valentine.phodal.com/) (ps:由于针对的是1920x1080的设备,所以图片在电脑上的效果可能不是很好,可以试试手机设备观看。) Github: [https://github.com/phodal/valentine](https://github.com/phodal/valentine)(ps: 觉得好的就给个star,不要光fork。)
';