高司令的新工作

By , August 31, 2011 9:45 am

高司令(James Gosling)8 月30日在其博客上发布了一篇题为I’ve move again的文章,宣布加入一家名为Liquid Robotics的创业公司。

Liquid Robotics的主要产品是用于远程数据采集的无人海上流动站。流动站通过海浪和太阳能获得能量,从而保持长时间的续航/工作能力。流动站上配备多种传感器,可以通过卫星链路、GSM或者WiMax等手段将数据发送到云端。流动站上配备多个GPS单元,从而使数据与时空(时间、位置)相关联。这些流动站能够以1~2节的速度巡航,这样的速度对于数据采集是非常合适的。到目前为止服役时间最长的一个流动站已经在海上漂流了两年半。现在一组这样的流动站正在墨西哥湾的Macondo油井工作,负责水质监测方面的工作。

传感器,数据链,云端分析与决策。这是一个典型的物联网应用场景。

和Java有任何关系吗?也许有。Sun 公司实验室(Sun Labs)曾经发布过一个名为Sun SPOT的产品。Sun SPOT是一个无线传感器网络平台,配备一块ARM处理器,集成了重力、温度、亮度等多个传感器和I/O接口,通过802.15.4协议进行通讯。与iMote等无线传感器网络平台的有所不同,Sun SPOT在处理器上直接运行一个称为squawk的Java虚拟机,开发人员可以使用Java语言开发Sun SPOT应用程序。作为“Java无处不在”的新尝试,Sun SPOT项目受到了James Gosling的大力支持。在2009年的JavaONE大会上,James Gosling就在玩具展示(Toy Show)环节做了一个Sun SPOT的演示。

Sun SPOT项目的总监是Roger Meike。他最近加入了RIM。关于Sun SPOT的更多信息,可以参考我之前写过的一系列文章《无线传感器网络教程(基于Sun SPOT)》。2008~2009年间我曾经以兼职讲师的身份在北京交通大学软件学院讲授《无线传感器网络 — 从理论到应用》课程,当时就是采用Sun SPOT作为参考平台的。

 

 

上学了

By , August 29, 2011 4:31 pm

过程很曲折,结局很完满。

已经不记得从多久以前就开始筹划清扬婉兮上学的事情了。考虑过自己教,最终觉得不合适;考虑过新加坡,甚至申请移民并且拿到了新加坡的Landing PR,但是举家搬到新加坡去住了一周后宣告放弃;考虑过私立学校,但是我们中意的私立学校竟然在2 月份的时候就告诉我们没有位置了;最后考虑的是我们家附近200米左右的一所公立小学,但是 --该小学的划片范围正好在我们家旁边哪条马路另一侧,而离我们家最近的另外一所公立小学在3 公里以外。我们租下目前住的这个房子的时候,只考虑了两个有利因素:(1)离我上班的地点很近,和(2)离我们中意的私立小学很近。我们没有考虑到的是:(1)中意的私立小学没有位置,(2)最近的那所公立小学实在太好。

好吧,我承认我的思想不纯洁了。可是当你面对200米外的超级小学和3000米外的普通小学这样的选择时,你会选择哪一个呢?这个年头,当你有钱也不知道该往哪里交的时候,你只能够选择找别人帮忙。

3 月初,写了一个入学申请书,介绍家庭情况,特别强调离学校特别近。申请书是写给市教育局的,但是因为要找到政府很困难,所以请一位做公务员的师兄转交。师兄在申请书上写了一点意见,大概是某某是个好同志请有关单位照顾为盼云云,又让我转交给另外一所小学的校长代为转交到教育局。这个过程,看似简单,却花了5 个月的时间。教育局收到这份申请书的时候,已经是7 月底了。

8 月上旬,楼底下贴出了3000米外那所小学的招生公告,我们小区果然在其势力范围之内。置之不理。

8 月中旬,各小学摸底登记报名截至。我们没有收到任何消息,有点着急。

8 月21日,该收到录取通知书的娃娃开始收到录取通知书。我们还没有收到任何消息,给师兄发了个短信求救,师兄回了个短信说“好的”。

8 月24日,该收到录取通知书的娃娃全部收到录取通知书。我们还没有收到任何消息,给师兄发了个短信求救,师兄回了个短信说“好”。

8 月27日,星期六,早上9 点收到电话通知去交赞助费1.5万元。当时正在文昌过周末呢,赶紧开车到海口,把占座费给交了。不收现金,不能转帐,只能到指定银行存现金到“海口某某装修工程有限公司”的帐号,然后凭现金存款收据换录取通知书。

8 月28日,凭录取通知书报名。晚上,发了个短信谢谢师兄。师兄回了个短信说“很好”。

8 月29日,开学典礼。

总算,我们家娃也有学上了。

 

 

CodeIgniter 2.0.2学习笔记

By , August 24, 2011 4:34 pm

如下学习过程是在Ubuntu 11.04 Desktop + AMP环境下完成的。

1、下载安装

访问http:/codeigniter.com/,有个“Downloads”链接。下载最新的版本CodeIgniter_2.0.2.zip。解压缩后把整个文件夹丢到/var/www目录下。

unzip CodeIgniter_2.0.2.zip

sudo cp -r CodeIgniter_2.0.2 /var/www/CodeIgniter

访问http://localhost/CodeIgniter,应该能够看到CodeIgniter的欢迎页面。

在/var/www/CodeIgniter目录下,分别有application, system, user_guide三个子目录,还有index.php和license.txt两个文件。其中,system目录包含了CodeIgniter的类库,而应用层面的工作基本上集中在application目录下。

2、快速上手

首先设置应用的根目录。编辑application/config/config.php,修改$config['base_url']参数:

$config['base_url'] = ‘http://localhost/CodeIgniter/’;

其次设置数据库连接参数。编辑application/config/database.php,修改$db相关参数:

$db['default']['hostname'] = ‘localhost’;
$db['default']['username'] = ‘root’;
$db['default']['password'] = ‘root’;
$db['default']['database'] = ‘CI_Test’;
$db['default']['dbdriver'] = ‘mysql’;

对于需要大量访问数据库的应用,建议自动装载数据库相关参数。编辑application/config/autoload.php,在文件的末尾增加一行:

$autoload['libraries'] = array(‘database’);

再次访问http://localhost/CodeIgniter/。如果你的数据库CI_Test尚未创建,你会看到一条错误信息Database Error。登录进入MySQL数据库,创建一个名为CI_Test的数据库。刷新一下浏览器,如果看到CodeIgniter欢迎界面的话就可以了。(如果没看到CodeIgniter欢迎界面的话,一般是数据库连接参数问题。)

CodeIgniter应用的入口定义在application/config/routes.php中。在2.0.2版本中,routes.php文件里定义了

$route['default_controller'] = “welcome”;

这个定义说明该应用的缺省入口为application/controllers/welcome.php。需要注意的是welcome.php的文件名和$route['default_controller']的定义是相同的。

看一下application/controllers/welcome.php文件,主要的部分如下:

<?php if ( ! defined(‘BASEPATH’)) exit(‘No direct script access allowed’);
class Welcome extends CI_Controller {
public function index()
{
$this->load->view(‘welcome_message’);
}

代码中$this->load->view(‘welcome_message’)这一句说明显示部分要去找application/views/welcome_message.php。看一下welcome_message.php这个文件,基本上就是HTML代码了。

接下来我们把这个例子稍微改装一下。编辑application/config/routes.php,修改如下:

$route['default_controller'] = “hello_world”;

创建文件application/controllers/hello_world.php,内容如下:

<?php if ( ! defined(‘BASEPATH’)) exit(‘No direct script access allowed’);
class Hello_World extends CI_Controller {
public function index()
{
$this->load->view(‘hello_world_display’);
}

创建文件application/views/hello_world_display.php,文件里头随便填一些内容,不是HTML格式的也没有关系。再次访问http://localhost/CodeIgniter/,浏览器里显示的就应该是hello_world_display.php的内容了。

通过上面的例子,CodeIgniter中的控制器(Controller)和视图(View)的关系就比较清楚了。

3、数据库查询

我们继续在前面的hello_world应用上进行修改。假设在数据库CI_Test中有一个名为User的表,这个表中有id, firstname, lastname, title等字段,其中id是一个自动增加(auto increment)的字段。为了方便测试,我们事先在User表中添加了一些测试数据。接下来我们可以创建如下hello_world_model,对数据库进行插入、查询、更新等操作。

<?php if ( ! defined(‘BASEPATH’)) exit(‘No direct script access allowed’);
class Hello_world_model extends CI_Model {

var $firstname = ”;
var $lastname  = ”;
var $title     = ”;

function get_last_ten_entries()
{
$query = $this->db->query(“SELECT * FROM User ORDER BY id DESC LIMIT 10″);
return $query->result();
}

}

接下来我们修改一下application/controllers/hello_world.php,如下:

<?php if ( ! defined(‘BASEPATH’)) exit(‘No direct script access allowed’);
class Hello_World extends CI_Controller {

public function index()
{
$this->load->model(‘hello_world_model’);
$data['result'] = $this->hello_world_model->get_last_ten_entries();
$data['title']  = ‘Hello World Page Title’;
$this->load->view(‘hello_world’, $data);
}
}

然后我们修改一下application/views/hello_world.php,如下:

<html>
<head>
<title><?=$title?></title>
</head>
<body>
<h1>CodeIgniter Hello World Application</h1>
<table>
<?php foreach($result as $row):?>
<p><tr><td><?=$row->firstname?>/<td><td><?=$row->lastname?></td><td><?=$row->title?></td></tr>
<?php endforeach;?>
</table>
</body>
</html>

刷新一下浏览器,应该可以看到数据库中个最后10条记录了。

4、数据库插入

接下来我们把这个例子改进一下,增加一个数据输入的表单。修改application/views/hello_world.php,如下:

<html>
<head>
<title><?=$title?></title>
</head>
<body>
<h1>CodeIgniter Hello World Application</h1>
<table>
<?php foreach($result as $row):?>
<p><tr><td><?=$row->firstname?>/<td><td><?=$row->lastname?></td><td><?=$row->title?></td></tr>
<?php endforeach;?>
</table>
<form action=”index.php/hello_world/add_entry” method=”post”>
<p>First name: <input type=”text” name=”firstname” /></p>
<p>Last name: <input type=”text” name=”lastname” /></p>
<p>Title: <input type=”text” name=”title” /></p>
<input type=”submit” value=”Submit” />
</form>
</body>
</html>

在上面这个代码中,我们增加了一个表单,处理该表单的URL为index.php/hello_world/add_entry。与该URL相对应的代码为application/controllers/hello_world.php中的add_entry()方法。修改application/controllers/hello_world.php,如下:

<?php if ( ! defined(‘BASEPATH’)) exit(‘No direct script access allowed’);
class Hello_world extends CI_Controller {

public function add_entry()
{
$this->load->model(‘hello_world_model’);
$this->hello_world_model->add_entry();
$data['result'] = $this->hello_world_model->get_last_ten_entries();
$data['title']  = ‘Hello World Page Title’;
$this->load->view(‘hello_world’, $data);
}

public function index()
{
$this->load->model(‘hello_world_model’);
$data['result'] = $this->hello_world_model->get_last_ten_entries();
$data['title']  = ‘Hello World Page Title’;
$this->load->view(‘hello_world’, $data);
}
}

在控制器hello_world的add_entry()方法中,又调用了模型hello_world_model的add_entry()方法。修改application/models/hello_world_model.php,如下:

<?php if ( ! defined(‘BASEPATH’)) exit(‘No direct script access allowed’);
class Hello_world_model extends CI_Model {

var $firstname = ”;
var $lastname  = ”;
var $title     = ”;

function get_last_ten_entries()
{
$query = $this->db->query(“SELECT * from User ORDER BY id DESC LIMIT 10″);
return $query->result();
}

function add_entry()
{
$this->firstname = $_POST['firstname'];
$this->lastname  = $_POST['lastname'];
$this->title     = $_POST['title'];
$this->db->insert(‘User’, $this);
}

}

上面这几段程序已经实现了通过表单提交数据并插入到数据库的功能。不过,在浏览器中显示的返回页面URL为http://localhost/CodeIgniter/index.php/hello_world/add_entry,不够美观。我们再次修改修改application/controllers/hello_world.php,在执行数据库插入操作之后将返回页面重定向到index.php。同时,在控制器hello_world的多个方法中都要加载hello_world_model模型,我们干脆在控制器hello_world的构造函数中预先加载。修改后的代码如下:

<?php if ( ! defined(‘BASEPATH’)) exit(‘No direct script access allowed’);
class Hello_world extends CI_Controller {

public function __construct()
{
parent::__construct();
$this->load->model(‘hello_world_model’);
}

public function add_entry()
{
$this->hello_world_model->add_entry();
$this->load->helper(‘url’);
redirect(site_url(), ‘refresh’);
}

public function index()
{
$data['result'] = $this->hello_world_model->get_last_ten_entries();
$data['title']  = ‘Hello World Page Title’;
$this->load->view(‘hello_world’, $data);
}
}

到目前为止,我们已经可以基于CodeIgniter来编写简单的MVC应用了。

 

收获

By , August 23, 2011 11:07 am


清平乐·村居
辛弃疾

茅檐低小,溪上青青草。醉里吴音相媚好,白发谁家翁媪。
大儿锄豆溪东,中儿正织鸡笼。最喜小儿无赖,溪头卧剥莲蓬。

去年八月的时候,在池塘里种下了一些莲藕。不过一年的功夫,已经是满塘的荷花。自七月以来,每个周末回家都有好多成熟的莲蓬。新摘下来的莲蓬,带着淡淡的清香,光是看着就让人喜欢。嫩一点的莲蓬,婉清和咪咪就剥开来生吃了。云舒尽管只有四颗门牙,也要抱着个莲蓬狂啃,过把干瘾。不过她一点也亏不着。我们把莲子剥出来,放在锅里蒸熟了,然后打成泥喂给她吃。最近她的消化能力好一点了,嫩一点的莲子也可以直接打成泥来吃,

嫩嫩的荷叶,摘下来放在白粥里,味道不错。

上周有个朋友到我们家来作客。咪咪作了一个荷花茶,真真是色香味俱全。可惜没有拍个照片。

 

A Dream on Satan

By , August 22, 2011 11:06 pm

Last night my fairest lady had a dream, on Satan.

In the dream Mimi came home with a bag. I asked what was in it and Mimi said it was Satan. Then Mimi brought out of the bag something with the size of a baby, and the appearance of a little devil. It looked mischievous, with a devilish grin. I asked, “why do you bring home a Satan?”. Mimi said, “There are two mis-conceptions about Satan. One is she is heavy, the other is she is evil. Since I can hold it in my arm it is obvioiusly not heavy. And now I am going to prove that she is not evil either.”

However, Mimi did not have enough time to prove that Satan is not evil. Our little daughter cried in her little bed, and we were both woken up.

(In the evening my fairest lady realized that the Satan she dreamed of was actually our little daughter. Hmmm…)

 

Panorama Theme by Themocracy