Blog

  • Microsoft Power BI初尝试

    最近测试了一下Microsoft Power BI Desktop。用的是我的藏书数据库。

    注意事项一:BID访问MySQL数据库需要安装MySQL .NET Connector,官方下载地址:http://dev.mysql.com/downloads/connector/net/

    注意事项二:BID不能单独Export图片,而只能用服务器端控件的方式显示。如下图。所以你还需要去官网下载Desktop并注册一个账号(特别注意:注册中的国家列表没有“中国”,但是你选择随便一个地方也无所谓;另外,不能用任何类型的免费邮箱)。

    还有很多要学习的地方。慢慢来。

    5.14补充:

    • 发现一个问题:我修改了图表,也已经publish,但是在本页面上还是显示老的图表。重新贴上BI里给出的链接还是老的图表。解决方法是克隆这个修改后的表格,再导出Web链接即可。
  • 而我就是莎士比亚

    莎士比亚就是我们自己,是忍受煎熬的凡人俗士,为不大不小的抱负激励,关心钱财,受欲念之害,太平庸了。他的背像个驼峰,驮着一种神奇而又未知何故显得不相干的天才……我们都是威尔。莎士比亚是我们众多救赎者中一位救赎者的名字。 ——安东尼•伯吉斯

    伯吉斯这本《莎士比亚》是我近年来看过的最让人愉快的莎士比亚传。

    文学评论自然应该讲作品。但是,一旦看过的书多了,读者自会形成自己的观点和看法,过于依赖他人的文字反而会是一种累赘。于是,读者想要看到的是作者此人的一些“故事”——或者说“八卦”,从而更全面地了解作者,更好地阅读他的作品。

    当年我读初中的时候,母亲的一位好朋友家中藏了一套《莎士比亚全集》(朱生豪译)。我记得那是我第一次借那么多书回家看。之后在1995年,我终于用自己那时还不很丰厚的工资买下了那套全集。

    更多的收藏随之而来:

    ==============

    我看他的戏剧作品,总感觉怎么也看不够。但是对他的诗歌——也是对所有的诗歌——不是太上心。这个是我的阅读偏好而已。

    就让莎士比亚这个老头子永远活在我的心里。

  • 什么是哲学?

    这本书是类似罗素的《西方哲学史》这样的一本哲学通论书籍。对于任何人——无论是对哲学一窍不通还是对哲学有粗浅认知——都有所裨益。

    书籍的组织非常传统:谁——说了什么——什么意思——简明批判。大致是这么一个框架。

    我很早开始接触西方哲学,也因此很大程度上忽视东方哲学的研读。这个倾向看来不会变了。

    但我总觉得哲学发展到如今,似乎到了一个关键的时刻。从实证论的角度出发,众多新定律、新现象对过往的哲学基础提出了挑战——如果不是推翻的话。在此前提下,哲学如果还是如当今的样子,恐怕会沦落到脱离现代社会的地步。

    我说这话,不是说我很欣喜地看到有那么多的鸡汤文学居然堂而皇之地冠以人生哲理的帽子——我对此向来嗤之以鼻。我是很遗憾地看到,没有真正的哲学新思想——更遑论新体系——在这样的一个大环境中产生,并起到哲学应有的作用:引领我们前进;和表达哲学的本意:对智慧的热爱。

    人需要生活无忧无虑,或者至少有“生活能无忧无虑”的期盼才会有机会跳出尘世的权术,进而思考更本质的问题。比如,我们如今不会去思考:我这样赚钱是对的吗?而只会去思考:赚钱是对的。因此,在这个意义上说,我们的社会在经历了如此长的发展,生产力、创造力得以如此大幅度提升后,实际上是倒退了。我们只是求生存,而不是求生存的意义。古希腊的哲学家是最幸福的。

    =========

    本书编排非常有意思。在每一章的结尾,都列出了若干思考题,可以供我们在看完一章后略微花点时间去思索一下。可惜,在这样一个实在的社会,我也没有更多的时间去这么做了。

    匆匆写就这些文字,就当是本书的读后感吧。

    及:本书的副标题是“哲学史里的快乐智慧”。英文原著的副标题是:The Unbearable Heaviness of Philosophy Made Lighter. 中文的翻译显然又是投机取巧了一把。

  • 这个民族有点怪

    在坐忘书房的推荐下,看了这本《菊与刀》

    2013年前,我一直不想去日本——理由不言自明。

    13年去了第一次,15年去了第二次。我对这个国家就再也恨不起来了。

    菊与刀

    只是一直没有很系统地去看看这个国家的一些更本质的东西。于是就在书友的推荐下,翻阅《菊与刀》。

    年纪到了一定岁数,读书到了一定的程度,看书就不一定是寻求新的东西,而是和自己的思考加以印证。看这本书的时候更是如此。书中结论和我平日构思基本类似。只是鲁思作为学者,更能系统地加以阐述吧。

    自从日本锁国的大门被打开以来的七十五年间,对日本人的描述总是使用一系列令人极为迷惑的“但是,又……”之类的词句,远非对世界其他民族的描述可比。

    这也是我的体会。

  • 该撞不该撞?该撞!

    最近有一件事,说的是在告诉路上的一次撞车事件。

    事件本身很简单,我就不再重述了。其衍生出来的问题却不简单。连白岩松都提了这么一个问题:法律上你没错,因此你撞上去没错,但是考虑到对方的生命安全,你撞上去是不是也就没有错了呢?

    咦?这好像是两个问题。一个是法律层面,一个是道德层面。

    我有两个基本原则,或者说公理。

    一,人的生命不可侵犯;

    二,任何人都不能干扰他人的决定,除非后者的该决定会影响前者自己的生命。

    我觉得在我们刚才所讲的康泰克之下,我的两个基本原则可以得出一个很自然的结论。

    那辆被撞的车的驾驶员是一个神志清醒的人,有判断力。那么无论他做出怎样的决定,都必须承担相应的后果。

    他的行为是严重违背安全的。为了达到自己超车的目的——虽然为什么要超车,为什么要赶时间的原因有多种多样——可以将后车置于极度危险的境地,也因此将自己置于极度危险的境地。

    他们做出这个决定的出发点也很简单:人是趋利避害的,所以后车应该能想到这个危险而加以规避。

    这样的出发点,会给他人带来危险,而更危险的是将自身的安全置于他人之手。所以,不论出于何种原因,后者“没有乖乖地”配合,这能怪后车吗?

    一个对自己生命和车上他人生命毫无责任感的人,指望起别人对他自己和他车上的他人生命负起责任吗?

    所以我是支持撞上去的。

  • 字母狗击败李世石

    今天真的是一个不平凡的日子:谷歌制造的AlphaGo围棋程序(昵称阿法狗,字母狗)再次击败李世石,在5番棋大战中,3:0取胜。

    多少年来,人们一直认为,围棋作为最复杂的游戏,计算机或者说人工智能要像职业高手那样玩出相当的水平还需要相当的年头。可是,这样的想法在字母狗的实力面前轰然倒塌。

    第一盘李世石的失利也许还能归咎于他不够认真,不够投入;第二盘字母狗37手天马行空且华丽无比的肩冲,第三盘角部的劫争,让我们对它最后一丝的怀疑也当然无存。

    围棋,也许到了重新被认识的时候。这么多年来形成的理论基础、定式、所谓的“俗手”……也许都要再次被重新判断一次。 这是AI了不起的胜利和里程碑,更是人类智慧了不起的胜利和里程碑。

    而我们,还在努力建设着一堵墙,努力地加快加剧和最新科技的距离。

  • 老彼得初中的最后一个学期

    今天老彼得学校开学了。初三下学期,初中的最后一个学期了。

    昨天晚上和他聊天——这也是我们每个学期开始前的谈话,这个习惯也保持了很多年了,我记得是从他小学一年级开始的。谈话的内容是问问他高中的打算:国内高中国内大学;国内高中国外大学;国际高中国外大学……选择也就那么几种。

    这个问题提出已经很久了,也一直在给他时间考虑,以及和我们、他周围的人更多的了解。比如他说这次开学班上有两个同学选择不参加中考,有一个还是他的死党,“学霸三人组”之一。

    我对他说,你的选择没有什么对什么错。我要的是你最喜欢、觉得最有趣的选择。所以他选择了“读国际高中,上国外大学”的道路。

    接下来,我要他给出TOP 3的理由,为什么选择读国际高中。他想了一下,给出的理由是:

    1. 自己英语最好。在国际高中英语环境中有相对优势。
    2. 自己善于交流。他认为国际高中的老师们应该也喜欢善于交流的学生,也会更善于和学生交流。
    3. 国际高中的课程将会更要求开放性和创造力。

    IMG_1287

    我再要他给出TOP 3的理由不读普通高中。他的理由是:

    1. 普通高中压力太大。“虽然明知在星海高中即便排在靠后(当然他的名次不算靠后)也能考上大学,但是还是有压力。”这是他根据他的观察以及与其他更高年级的小伙伴们沟通得到的结论。
    2. 课程比较死板,2年学完3年的课程,实在很紧张。
    3. 自己的优势得不到发挥。

    接下来,我挑战他的一个open question是:

    • 在国际高中,他的优势是否还会成为优势?如果是,为什么?如果不是,该如何应对?而他想回避的在普通高中会碰到的问题,在国际高中是不是也会同样出现?如果出现,又该如何应对?

    这个问题我没有要求他马上回答,而是要他好好想想。

    他的决定和我们的想法还是基本一致的。所以,从我们家长的角度来说,就是去支持他。

  • 微信订阅号的开发

    最近看了一下微信订阅号的开发。

    我要做一个个人订阅号,用户订阅之后,可以通过输入命令获得交互,得到英文单词的解释,大概就是这样。

    微信开发权限获得就不讲了,需要帮助的同学可以去访问相应的站点。

    首先,我开了一个域名(http://weixin.rsywx.com) 作为和微信通讯的接口。

    按照微信的说法,用户输入命令后,该接口将“被动”地回复信息。而这也是我这个订阅号和用户交互的主要渠道。

    在weixin.rsywx.com中,我用Silex框架构建了我的应用。这是因为我需要在这个框架中进行一些控制。当然你也可以用一个plain PHP文件来完成这个接口的工作。 该应用的入口文件很简单:

    require_once __DIR__ . '/../vendor/autoload.php';
    require_once __DIR__ . '/./WechatCallbackAPI.php';
    $app = new Silex\Application();
    $app['debug'] = true;
    // Twig registration
    $app->register(new Silex\Provider\TwigServiceProvider(), ['twig.path' => __DIR__ . '/../views']);
    $app->post('/', function () use ($app)
    {
        $obj=new WechatCallbackAPI();
        echo $res=$obj->response($app);
    });
    $app->run();

    其中的Twig注册不是必要的,因为微信要求的回应是一个XML字符串。不过放进去也没有关系。 对于“/”这个路径,我们在响应微信的请求时必须使用POST方式。同时我们创建了一个对象,并调用response方法来返回消息。 在WechatCallbackAPI中,我们抄袭微信的实例代码并作一些改进:

    public function response($app)
        {
            $post=$GLOBALS['HTTP_RAW_POST_DATA'];
            //$post=file_get_contents('php://input');
            if(!empty($post))
            {
                libxml_disable_entity_loader(true);
                $obj=simplexml_load_string($post, 'SimpleXMLElement', LIBXML_NOCDATA);
                $from=$obj->FromUserName;
                $to=$obj->ToUserName;
                $key=strtolower(trim($obj->Content));
                if($key==?||$key==?||$key=='help')
                {
                    $wpme=new WPME($from, $to);
                    $res=$wpme->help();
            return $res;
                }
                else if (substr($key, 0,4)=='wpme')
                {
                    $wpme=new WPME($from, $to);
                    $wpme->setKey($key);
                    $res=$wpme->invoke();
                    return $res;
                }
                else if(substr($key, 0,4)=='wotd')
                {
                }
                else
                {
                    $wpme=new WPME($from, $to);
                    $res=$wpme->unknown();
                    return $res;
                }
            }

    注意,这里还用到了一个在PHP 5.6中被标记为deprecated,而在PHP 7将是obsolete的功能:

    $post=$GLOBALS['HTTP_RAW_POST_DATA'];

    PHP手册中建议用

    <pre lang="php">$post=file_get_contents('php://input');

    但是经过测试似乎不行。微信就是这么任性。

    在该response函数中,我们根据不同的用户输入来调用不同的功能。上述代码中列出了WPME(Word Power Made Easy)模块中的判断。WPME模块中最重要的方法是invoke,它将根据不同的命令($key)去进一步调用不同的资源并构造返回值。而另外一些命令在WPME中直接处理,比如最简单的help方法:

    public function help()
        {
            $content = Available commands:\nwpme1: Latest WPME\nwpme7: Last 7 WPMEs\nwpme????: Search WPME for ????;
            $res = sprintf(WPME::$txtTemplate, $this->from, $this->to, time(), $content);
            return $res;
        }

    help将列出可以使用的命令,比如wpme1,然后渲染一个静态文本模板并返回。文本模块的格式可以参考微信文档。

    而invoke方法如下:

    public function invoke()
        {
            $uri = https://rsywx.net/wechat/ . htmlentities($this->key);
            $content = file_get_contents($uri);
            preg_match_all('/(.*?)<\/title>/i', $content, $matches);
            $res = sprintf(WPME::$newsTemplate, $this->from, $this->to, time(), $matches[1][0], date('Y-m-d'), $uri);
            return $res;
        }

    我们可以看到,我们的一般命令将返回图文信息。而图文信息的模板格式也请参考微信文档。这里我们并不进行任何实质性的处理,真正的内容渲染我们在另外一个站点:https://rsywx.net 中进行。

    rsywx.net是一个之前我单独开发的站点,考虑到微信使用的一些功能可以在该站点中复用,所以我将微信需要的返回信息的功能(控制、数据、呈现)放在这里实现。这个站点用Symfony完成。其实,我这个微信号最本质的内容呈现逻辑都是在rsywx.net中完成的。

    我们看一个indexAction方法。这个方法接受来自weixin.rsywx.com的调用,并根据不同的关键字进行处理:

    public function indexAction($key)
        {
            $entity = substr($key, 0, 4);
            if ($entity == 'wpme')
            {
                if ($key == 'wpme1' || $key == 'wpme7')
                {
                    $uri = http://api/$entity/$key;
                    $res = json_decode(file_get_contents($uri))->out;
                    $theme = $this->container->getParameter('theme');
                    return $this->render(AppBundle:$theme/wechat:$key.html.twig, ['res' => $res->res]);
                }
                else //The key is like wpme????, where ???? is the search term
                {
                    $search = substr($key, 4);
                    $uri = http://api/$entity/s/$search;
                    $res = json_decode(file_get_contents($uri))->out;
                    $theme = $this->container->getParameter('theme');
                    return $this->render(AppBundle:$theme/wechat:wpme7.html.twig, ['res' => $res->res]);
                }
            }
        }

    如果从weixin传来的命令是wpme1(列出最新的单词)或者wpme7(列出7个最新的单词),那么rsywx.net将进一步调用http://api.rsywx.com 中相应的RESTful API接口获得数据并渲染;如果是类似wpme????这样的命令,那么将进行搜索,并将结果返回。

    最后我们来看http://api.rsywx.com ,如果我们直接访问这个站点,将会呈现该站点所提供的所有接口的API文档:

    Ashampoo_Snap_2016.02.01_20h46m03s_002_Chrome

    而在这个站点中,我同样用Silex框架实现了对应的方法来返回数据(实际上,rsywx.net的所有数据也都是由该站点提供的)。

    好了,如果你现在在公众号中输入这样的一个命令:wpme1,你将看到如下的界面:

    Screenshot_20160201-205011

    Screenshot_20160201-205018

    怎么样?是不是很酷?

    本文收录于[go4pro.org]

  • 对独裁的抗争

    《The Death Of Caesar》是一本讲述历史上最著名的一次刺杀的书。

    ==========

    我们所学的历史基本只讲谁是凯撒,谁又在何时何地刺杀了他,然后安东尼和屋大维为凯撒复仇,最后屋大维又战胜了安东尼,成为新一代的凯撒。

    而这本书的独特之处在于讲述了刺杀的谋划,刺杀当日的情形,刺杀之后民众、参议院、各方的反应,以及漫长的对抗:一方以Brutus和Cassius为代表,一方以Anthony和Octavian为代表。他们如何联合各方势力,运筹帷幄,又犯了怎样的错误,而最终导致我们所看到的历史。

    本书立意的独到之处是为那些从历史来看是失败者的人们立传。作者希望我们的视角不要仅仅停留在凯撒、安东尼、屋大维身上,而更多地去看看那些失败者:他们到底是为了什么而谋划了这一场历史上最著名的刺杀。

    书结尾的一句话可以代表作者的用意:

    They had been transformed, rendered powerful reminders that as long as men and women remember the names of those who killed Julius Caesar, dictators will not sleep safely.

    所以,这本书是对那些独裁者的警告。只要人民还能记住那些刺杀了凯撒的人的名字,独裁者将无一日能得安眠。

    ==============

    罗马共和国到罗马帝国的转变,可以说就是由凯撒被刺杀开始的。前三巨头(克拉苏、凯撒、庞培)时代先是形成后三巨头(安东尼、雷必达、屋大维)再到屋大维获得凯撒封号成为第一任皇帝最后到了1500年后被土耳其人攻陷。这段历史几乎是西方历史的全部——至少也是重量级的一部分。

    Brutus是传统的共和国的拥趸,他对凯撒所表现出来的独裁具备着根深蒂固的憎恶和不满。罗马共和国也许有机会在凯撒被刺之后延续更多年代的共和体系,但是这一切都没有发生。历史选择了屋大维,并最终将罗马带入了帝国时代。

    公元前221年秦朝建立了中国历史上第一个帝制国家。罗马帝国陨落,欧洲中世纪结束的那一年(1453年),英法百年战争也结束了,中国处于明代宗的年代,还将有约莫500年才由中山先生发动辛亥革命推翻帝制恢复共和。在欧洲相对地理开放、封建林立的大环境下,罗马帝国存在如此之久确实也是一个奇迹。

    看历史书往往会有代入感——这恐怕也是历史穿越小说长盛不衰的一个原因。如果你回到公元前44年的Ides of March,你会站在哪一边?你是义无反顾地加入反抗帝制的一方,抑或顺应历史潮流与安东尼、屋大维联盟?想想都让人兴奋不已。

  • 我关闭了微信朋友圈

    昨天决定关闭微信朋友圈。

    有这么几个原因。

    1. 关闭朋友圈不会影响我收发红包。
    2. 朋友圈的设计不是用来扩展朋友圈,而是限制朋友圈。
    3. 转发机制很不友好。
    4. 最近微信朋友圈推广的一些活动让我很不耻。

    不过我还是会维护微信订阅号。