Explore. Dream. Discover.

Samuel Chen's life

Twenty years from now you will be more disappointed by
the things that you didn't do than by the ones you did do.
So throw off the bowlines. Sail away from the safe harbor.
Catch the trade winds in your sails.

Explore. Dream. Discover.
—— Mark Twain

2012年3月11日星期日

改变使用方式,重定义一个行业

我一直比较喜欢和敬佩能改变或重新定义一个行业一个产业的人和公司,Bill Gates 改变了人们使用电脑的方法,Jobs 重新定义了手机,任天堂将游戏从桌面带到了屏幕,又从沙发带到了客厅,从家里带到了身上,facebook 把社交带到了电脑(准确来说,虚拟人生很早就在做这个事情),Google改变了互联网的入口,亚马逊、Google 等改变了计算方式,等等等等。

今天,互联网和移动终端,我们都知道,正在改变这个行业,大家或多或少,或清晰或朦胧的感受到、预见到那些正在以及可能产生的变化,也一直在寻找,我也一直在思考,到底会是怎样。也许有一天,只是一只手指,轻轻的触碰到了那一点,刷的一下,就豁然开朗。

一直在思考,究竟我们能改变什么?上面那些变化,都是大的公司,在强有力的支持下做出的(除了facebook),也许一个小公司小团队很难做到,但谁知道呢。

云和端,云很重要,但它实际上是一个载体,就好比互联网,再怎么发展,也是一个工具。而云就是各种业务,应用的一个载体,或许会有一天有天翻地覆的变化,但现在,我能看到的,云是一个很重要的基础设施,要想从这上面想象变化,暂时还没有突破口。

而端,或者说客户端、消费端,由其表现形式,已经能呈现出非常丰富的变化。而最有可能重新定义的就是软件/应用的消费方式。比如,可能是一个冰箱同步你的菜谱并自动调温,可能是一个闹钟同步你的日程还报出内容。手机端,是一种设备,由于各家巨头都看到了,它也是表现能力非常强的一种设备,正在改变人们消费数字产品的方式,从桌面带到了街头。

由于其他的设备的发展还不很明朗,所以我想谈谈手机(平板,智能手持设备)可能的带来的改变。

那么手机有哪些特点?

  • 首先我们第一个想到的肯定是移动能力
  • 其次是小尺寸的屏幕(视觉输出)
  • 接着是加入的GPS定位能力(地理方位输入)
  • 再就是拍照、摄像(视觉输入)
  • 还有重力感应(方向和速度输入)
  • Siri让我们想起了手机还有语音输入的能力(是不是很奇怪,手机一直都能通话,但这么久才有这个功能,语音识别技术早在上世纪90年代就有了)
  • 另外还有指南,湿度,高度识别等等(方位,湿度,温度,高度的输入等)

注意我第一段说的那些改变,基本上都不是技术上的革命,而是使用方法的革命。就拿Siri来说,典型的旧瓶装新酒,语音识别+wolfalpha+LBS+Schedual 等等,都是早已出现的技术。

所以我想说,最重要的是方式的改变。借着手机这么丰富的传感功能,也许我们能探索到一些改变某件事情的方法,将互联网和传统结合,走出点新路。

就拿阅读这件事情来说,什么是阅读?阅读什么?为什么阅读?什么时间阅读?什么位置阅读?什么天气阅读?文字、图片、视频可以阅读大家都知道,但声音能阅读吗?关系能阅读吗?知识能阅读,能力能阅读吗?善恶能阅读吗?阅读能变成游戏吗?阅读能传递吗?无数个想法。Kindle正在改变阅读的载体,阅读的方法呢,也许将来是直接注射的,就好似嫁衣神功一般。

思想风暴,想想看阅读和手机传感结合能有什么方式?

  • 阅读内容的改变。除了文字和图片,视频也是可以阅读的,但其他的阅读,受限于内容和表现形式暂时没有想到更好的。视频的阅读,除了播放之外,1)可以拆分成图片+字幕的方式像漫画一样阅读。2)可以用语音视频读出视频内容,以文字方式阅读。3)看视频的时候同时阅读视频的相关信息比如导演,主演,内容介绍,评论等(已经有网站把评论作为视频的字幕在上下两侧飞过)。总的来说,视频是另外一种内容消费方式,和阅读挂钩丧失了原有的魅力。
  • 文字与图片的阅读,小屏幕的限制解除,重新排版,转换格式
  • 阅读的时候看看附近的人都在阅读什么
  • 看看当地的新闻
  • 旅游地的文字资料
  • 长途驾驶对地标照相,自动产生路书并读出来
  • 两人站在一起晃晃手机就交换了阅读内容
  • 拍摄报纸一角剪报,识别,存档,日期地点等
  • 路上看到个海报,拍下来,识别后,自动为你找到相关内容随身看
  • 平板的阅读方式又和手机不同

总的来说,阅读是一种输出的应用,对输入的要求较少,如何利用传感输入可以是一个思路。更进一步的是改变设备的输入输出方式,比如全息,当然这个在技术上和产业实力上都不是一个小事。现在这么多人和企业都在做手机和移动设备,除了一些跟着捞一把的小企业,相信大多都是看到了这些。

其他的,比如内容的存储,存的越多,手机抖的越厉害。比如有CMS和CRM,为什么不能有RMS,好过现在通讯录。再有,有游戏,有SNS游戏,有MUD,为什么不能有社交关系地理位置的轻游戏或者RMS,比如根据高度差,根据甩手机的重力程度,来攻击,或者不叫攻击叫骚扰,你的朋友(一个同事介绍的LBS游戏给的灵感)。根据通话、短信频率确定关系远近,等等等等。

随想。

标签: ,

2011年6月18日星期六

下一代互联网初见端倪

现在的互联网,以及所谓的物联网,争的是两块,一块是服务端,也就是云端,另一块是终端。

云端现在是Amazon, Google暂时领先于基础架构领域,MS, Apple 处于追赶之中,Facebook/Twitter则领先于SNS(此SNS含义相当广,包括身份,信用,关系,服务,应用等等)方面。传统厂商如IBM, HP基于其固有的优势,大力推广所谓私有云,实质是企业cluster,在下一代互联网中已经落后一步。

而终端则是Apple,Google 和 MS 三足鼎立。iOS和Android,已经成为了移动领域事实上的领头羊,MS在桌面的固有优势以及家庭媒体中的发力,使其保持在第一梯队中。而HP,虽然购买了3Par, Palm/webos,但依然未能表现出足够的进取。其他厂商,目前看来,只是陪太子读书的角色。

标签: , , , ,

2011年4月15日星期五

python 的编码,关于 encode, decode 的简单原则

Python 中 encoding 的处理其实已经很简单了,根据我这近一个月来用python的经验,有一个简单的原则可以作为参考。

基于python 2.7
1. 类型要清楚, unicode 不是 str
2. decode 之后的结果都是 unicode
3. encode 之后的结果都是 str,其编码是你encode的参数
4. 输出一律用 str
5. 存取一律用 unicode

 就这么简单,编码基本上就不会错了。 
举个例子,有个GBK编码的文件 name.txt,每行一个人名

for line in open('name.txt').readlines():
    print line  # 这时候 line 都是 gbk 的 str 
    x = line.decode('gbk')  # 转成 unicode了 >> 建议这么做, 原则: 但凡输入的,一律转换成unicode后处理
    print x  # 输出 unicode >> 不建议这么做
    print x.encode('utf-8') # 输出 str >> 建议这么做,原则:但凡输出,一定编码成str
    store_to_db(x)   # 这时候存的都是unicode
    my_str = x.encode('big5') # 转成 big5了
    print m_str   # 输出的是 big5 的 str

此外,encode 的时候不一定会成功,这时候会raise一个exception,这是因为 encode 还有一个参数用来控制encode失败后的处理,default是strict,也就是抛异常。

你可以用 encode(src, 'replace') 来处理,replace就表示碰到转不了的,用问号'?'来代替,而不是抛异常。

具体用法,查文档。

同样,输出的时候,输出流也需要有编码。比如stdout默认是ascii的,而你要输出unicode,就需要得到一个基于unicode的输出流,output = codecs.getwriter('utf-8')(sys.stdout)


标签: ,

2011年4月2日星期六

web.py 在 apache + fastcgi 配置 tips

根据web.py官网的说明,配置使其运行在apache + fastcgi 上,碰到了许多问题,耗了两天时间才整明白。一方面是apache的配置不熟悉,另外一方面是其官方文档也有些疏漏,问题及解决办法如下(ubuntu 10.04):
  • 调试日志
    web.py 应用挂在服务器上以后,stdout/stderr,都好像转了(查网上的,未验证),另外apache的用户是www-data,用户当前目录也是没有权限,所以logging要记录在/tmp下,或者单独建一个/log目录给写权限才行,这个一般规划好了没什么问题。
    另外,也可以做个ApacheLogHandler来将日志记到apache的日志文件中,这个网上可以搜到。
    然后就是,apache的日志文件在/var/log/apache2/ 。如果你的网站配置文件修改了日志位置,要注意这个地方只记录了一部分,还有一些仍然会记录在default位置。
    最后,可以使用traceback包来记录未处理的异常,代码如下:
    
    try:
        # web.py code
        # urls = ...
        # ...
        # app.run()
    
    except Exception, e:
        f = None
        if os.name == 'posix':
            f = open('/tmp/yule_unhandled_error.log', 'w')
        else:
            f = open('%s/yule_unhandled_error.log' % os.environ['temp'], 'w')
        traceback.print_exc( file=f )
        traceback.print_exc( file=f )
        f.close()
    
    
  • python 库路径 (PYTHONPATH)
    在 apache + fastcgi 中运行 python cgi,如果你使用了 PYTHONPATH 来引用库,你会发行看到的永远是 500 Internal Error。这是因为apache没有复制shell中的环境变量。
    注意,不要使用envvar文件,或者在网站配置文件中用setEnv,passEnv 等方法,这些方法我试过完全没有用。
    你要做的是,用代码将所有的路径全部都加到sys.path中。代码如下:
    
        import os, sys
        python_path = "/you/python/lib/path:/you/python/lib/path2".split(':')
        for path in python_path:
            sys.path.insert(0, path)
    
    
    当然你可以检查path是否已经加入了,注意路径访问权限,牢记现在的用户是www-data。
  • 静态文件
    好了,现在都配好了,再访问网站 ... OK 出来了!
    等等! 怎么搞的,样式表,图像怎么都显示不出来了?
    原来是web.py 官网的配置文件有少许疏漏,静态文件的转发不对!
    假设静态目录是网站根下的 /static/ (这也是web.py的推荐位置),那么我们要做的是修改网站配置文件的mod_rewrite 规则为:
    
    
        # 修改 ifmodule 这一节,注意蓝色行
           RewriteEngine on
           RewriteBase /
           RewriteCond %{REQUEST_URI} !^/icons
           RewriteCond %{REQUEST_URI} !^/favicon.ico$
           RewriteCond %{REQUEST_URI} !^/static/  ### 注意这一行 
           RewriteCond %{REQUEST_URI} !^(/.*)+code.py/
           RewriteRule ^(.*)$ code.py/$1 [PT]
    
    
    
好了,现在再试试,是不是已经好了 :)


标签: , , , , ,

2011年3月5日星期六

Django 如何在模板(template)中使用settings中预定义的变量


在Django中编写模板(template)的时候,有时候可能会用到settings中设定的变量,比如说STATIC_URL。此时,如果你直接使用 {{ STATIC_URL }} 是取不到值的。那么怎么才能在模板中使用呢?难道非得在每个view中添加到context中吗?

答案是否定的。根据Django文档中所描述,我们至少有两种方法可以直接使用。http://docs.djangoproject.com/en/dev/howto/static-files/#referring-to-static-files-in-templates

方法1:

使用 {% load static %} 载入 static 模块,然后使用 {% get_static_prefix %} 就可以了。
{% load static %}

<img src="{% get_static_prefix %}images/hi.jpg" />
当然也可以将其定义为变量以多次使用
{% load static %}

{% get_static_prefix as STATIC_PREFIX %}

<img src="{{ STATIC_PREFIX }}images/hi.jpg" />
<img src="{{ STATIC_PREFIX }}images/hi2.jpg" />

方法2:

这个方法是推荐的方法,直接使用 RequestContext 来传递。其原因就是因为settings中定义的变量都会在request中传递,但是response的时候是没有这些context的,所以Django专门定义了RequestContext来帮你组合(其实你自己也可以做这件事)。


#注意这里是django.template,由此可见是专门为template设计的
from django.template import RequestContext

def some_view(request):
    # ...
    return render_to_response('my_template.html',
                              my_data_dictionary,
                              context_instance=RequestContext(request))

这个实际作用就是将request中的context全部都加到response的context中去。

这样,你就可以直接在模板中使用{{ STATIC_URL }} 来使用了,当然其他的变量也是可以的,不需要每个都单独去load了。

标签: ,