一直以来我的手机就不太稳定,但最近的表现还是有些过分,在接过一次电话后就再也接不到电话,必须得重启才能解决问题。当然,这或许和我新刷的非官方ROM有关。
再次漏接电话后,做了一个拍脑袋的决定,到淘宝去订购了个黑莓的手机。
感觉多少有些不可思议,本来一直没多少换手机的想法,然后忽然就决定了,而且还是黑莓。
估计后天就可以到货,到时候看看黑莓的体验怎么样。
一直以来我的手机就不太稳定,但最近的表现还是有些过分,在接过一次电话后就再也接不到电话,必须得重启才能解决问题。当然,这或许和我新刷的非官方ROM有关。
再次漏接电话后,做了一个拍脑袋的决定,到淘宝去订购了个黑莓的手机。
感觉多少有些不可思议,本来一直没多少换手机的想法,然后忽然就决定了,而且还是黑莓。
估计后天就可以到货,到时候看看黑莓的体验怎么样。
昨天收到网友的邮件说我做的农历插件无法使用。但我自己测试却没有发现啥问题。于是在自己的虚拟机里测试了下,还真无法工作了。
检查代码发现里面有runCommand(‘cal’),这样的代码。去查了下,发现cal是linux查看日历的命令。估计是新版本的yahoo widgets去掉了相关命令的支持。重新下载了个yahoo官方的日历组件,将runCommand(‘cal’)用新版yahoo插件中相关代码替换后我的widget终于又可以正常工作了。
我的这个农历组件已经发布两年多了(看截图:-),直到现在才有人给我反馈(不过,我也不知道从啥时候开始出问题),看来这东西还真没几个人用。
五岳归来不看山,黄山归来不看岳。
去过黄山之后,登山的选择似乎就变得很小了。抱着地图看了一圈,距离比较近的似乎就只有三清山可以去去了。
话说三清山也算是很早就想去的一个地方了。虽说三清山并不算太出名,但三清山人有一套不错的说辞。徐霞客将太多的词语给了庐山,似乎庐山已经是最好的了。游览过三清山后却叹一山还有一山高,一时词穷,所以索性封笔。虽说这多半是后人的戏言,却让我多少还有些心生向往。
很多去过三清山的人都对三清山有不错的评价,说三清山接近黄山。确实只是接近而已。从某些角度上说三清山有些地方和黄山还是有几分相似之处,不过三清山却比黄山要俊秀不少。如果说黄山是一个大家闺秀,那三清山就只能是小家碧玉了,虽有几分姿色,却也难登大雅之堂。
本在出行前就基本上将行程给安排好了,但最终计划基本上全部乱了,把一切搞得一团糟。不能说三清山不好,只是由于一些主观和客观原因让这次的行程没有预想的愉快。
最初的计划是在山上住一晚,但看网上的介绍似乎没有这个必要。事实证明确实没有这个必要。相比黄山而言三清山要小了不少,如果安排合理一天下来绝对绰绰有余(但是我的安排完全砸锅了)。
在出发前就到网上找好了导游图,并做了个基础的行程安排。到景区后又买了两张导游图。这里的导游图一张不同一张,而且更糟糕的是,似乎没有一张是正确的。最终导致我将东/西栈道走了两遍,然后没能逛完南清园(主要景区之一),最糟糕的是还错过了最后一班回玉山的公交。
我并不是对所有的托都特别的反感,我相信大多的托多少还是有些职业道德的。有些东西反正是需要的,让人介绍介绍,买卖成了大家高兴也并无什么不好。却不想这次遇到了没啥职业道德的托。说得好像只此一家,后面还要加上一句,我真的不骗你。不骗才怪。
栈道结冰,大家依次扶着围栏缓慢的移动。前面的那位大小姐一路叽叽YY的抱怨个没完没了。对面过来一位小姑娘,结果两人面对面的站了几秒,然后对面的小姑娘小心翼翼的让开。这位大小姐开始愤愤不平的抱怨到,也不知道让一下。苍天啊,如果对方是个男士你还可以说对方没有绅士风度,但你凭啥非得要一个和你年纪相仿的小姑娘给你让道。为了避免耳朵生茧,我绝对先行一步。走的时候不小心小滑了一下。这位大小姐轻蔑的说啥“超、超、超……”。我想要是我真的滑到,她还不得乐掉大牙。真想回敬她一句。不是我想超,实在是受不了你的鸡婆。
虽然django的admin漂亮的实现了CRUD,不过在有时候admin并不是这么好用。然后开始进行手写CRUD,接着发现自己又陷入了重复操作中。相比而言Ruby自动生成的添加删除功能就好不少,你生成的基础框架是可以扩展的。
为了减少手动书写CRUD的工作量,我写了一个扩展的startapp command。使用这个命令会自动生成 list/new/edit 的操作和html文件(这样修改起来就方便多了)。
如需要在其他工程使用该命令,只需要将项目中的django_extensions文件夹复制到其他工程的app目录,并在settings.py里把django_extensions添加到app列表里。该扩展命令为create_app,使用方法和django官方的startapp一致(如:manage.py create_app blog)。
为了方便演示,该扩展命令包含了一个演示工程(hidjango)。下面的步骤是windows平台(因为用了几个bat)。
/django_extensions/conf/app_template/
|~templates/
| `~{{ app_name }}/
| |-base.html
| |-edit.html
| |-list.html
| `-new.html
|~templatetags/
| `-__init__.py
|-__init__.py
|-admin.py
|-forms.py
|-models.py
|-tests.py
|-urls.py
`-views.py
django使用app机制来实现组件的重用,充分的利用已有的app可以极大的简化开发工作。目前django下的app虽然还不够丰富,却也还是有部分不错的。django-tagging就是一个不错的app。
现在tag的应用非常广泛,tag基本上成了各网站的必备项目之一,django-tagging就是一个提供tag功能的app。django-tagging提供的功能非常丰富,使用起来却十分简单。下面我就介绍一些常用的用法,让大家对该app有个基本的了解,更详细的介绍还是老老实实的去看django-tagging的使用说明吧:)。
我们先定义一个数据库模型Widget,下面的范例都用Widget来进行说明
class Widget(models.Model):
name = models.CharField(max_length=50)
tags = TagField()
就如上面的代码,只要在数据库模型中增加tags字段就可以为该对象提供tag支持了。tags被映射为CharField,在为对象添加tag时为,英文逗号分割的字符串如:
Widget(name='hello', tags='test,hi,hello')
这样就为新建立的对象添加了test hi hello三个tag了。
获取某个tag下的所有对象的代码如下:
#取出所有属于TAG hi的对象
tag = get_object_or_404(Tag, name='hi')
widgets = TaggedItem.objects.get_by_model(Widget, tag)
如要取出Widget用到的所有tag的代码为:
tags = Widget.tags.all()
现在不少python程序都是用reStructuredText写文档。
比较郁闷的是有部分文档都只提供了reStructuredText的源文件,没有转换好的html文件。
感觉自己每次手动转比较麻烦,于是花了点时间写了个在线的。
将reStructuredText文件贴进去,提交后就可以看到转好的页面了。
现在还有点问题,sphinx对reStructuredText进行了扩展。
对包含了sphinx标签的会处理出错(谁知道怎么忽略错误?)。
地址是 http://rest.haoluobo.com/
程序的代码可是非常的少,主要代码就是下面几行。
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
from django.http import HttpResponse
from docutils.core import publish_string
def index(request):
html = """
<html>
<head></head>
<body>
<form action="" method="post">
<textarea name="rest" cols="60" rows="20" onfocus="this.value=”"></textarea>
<br/>
<input type="submit" value="提交"/>
</form>
</body>
</html>
"""
if request.POST:
html = publish_string(request.POST[‘rest’], writer_name=’html’)
return HttpResponse(html)
stardict是linux下使用最广的字段程序,在广大网友的贡献下,stardict的字典文件可是相当的丰富。pystardict是一个读取startdict字典文件的python库。
前些天在邮件列表看到有人提到用pystardict加载stardict的字典文件速度慢的问题。加载字段文件时需要解析字段的索引文件(.idx)取出所有的单词信息。但python未提供指针,处理速度远比不上c。
我尝试用正则表达式对索引解析部分的代码进行重写,经测试,速度应当能提高3/5的样子。感觉依旧不是太理想,不知道是否还有什么别的办法。
我将改动后的代码生成了一个patch发给pystardict的作者,不知道是否会被采用。
下面是idx解析的关键代码(idx的结构确实是非常的简单):
import re
rawstr = r"""([\d\D]+?\x00[\d\D]{8})"""
matchstr = self._file
match_obj = re.findall(rawstr, matchstr)
for e in match_obj:
c = e.find('\x00')
record_tuple = unpack('!%sc1x%sL' % (c, idx_offset_format), e)
word, cords = ''.join(record_tuple[:c]), record_tuple[c:]
self._idx[word] = cords
今天收到原作者的邮件,我提交的patch已经接收了,新的pystardict已经更新过。不过他用的是我早些提交的patch。那个patch里,我unpack的时候没有做跳过\x00的处理,所以要稍微丑点。
前些天在37signals的主页,看到他们又出新产品了。Highrise,一个CRM管理工具。我虽然对CRM了解的不多,却也看过几个其他的CRM。那些CRM给我的感觉都是十分复杂。Highrise倒是出奇的简单,在我看来简单到就和一个通讯录差不了多少了。
然后又去翻看了下那本讲述他们产品设计理念的Getting Real。
或许就如书中讲的一样,现在的大多产品不是功能太少,而是有着太多不必要的功能。
一个产品要增加功能是很容易的,将世面上同类型的软件浏览一遍,看看别人都有些什么功能,这样你很容易就可以得到一长串的功能列表。人们总是想当然的觉得功能越多越好,但功能的增加在很多时候也意味着使用复杂度的增加,同样随之而来的还有开发的工作量以及延期的危险。
很多时候我们都是理所当然的认为别人有的我们也要有,却很少真正想过到底哪些才是用户真正需要的。
我以前的公司曾有一套OA系统。直到用了很久后我才发现里面居然有提供通讯录和日程安排,因为这些功能根本就没人用。这个系统虽然提供了非常多的附加功能,但真正在使用的也就公告、工作流和站内消息(后来站内消息也基本上被邮件给取代了)。
我开发过的产品也存在类似的问题。人们真正用的也就里面一两个核心功能而已,那些花了很大力气开发的功能,事实上根本就没什么人用。当然,有些是商务上的考虑,那些所谓的功能只是忽悠客户而已。
每个人都有自己的边界,对于公司而言,每个公司也都有自己的边界。37signals是一个小得夸张的公司,他们甚至没有专职的产品策划(不知道现在有了没)。在我看来,对于这样的公司,团队中的每个人都应当参与到产品的策划中。他们擅长的小型团队的协作开发,这在一定程度上也是他们的边界。也正是如此,他们此前开发的产品都和小型团队的协作有关。在一定程度上说,他们是他们产品的目标客户。
就他们现有的客户类型而言,我想他们应当用不到CRM管理系统。也就是说,他们可能不是自己产品的目标客户。不知他们是怎么提取需求(Getting Real)的,或是有请专门的咨询师?
乱七八糟的想了不少,然后写出来也是乱七八糟。或许是我无法做到所谓的Getting Real。
今天在服务器上将老照片给部署好了,关闭许久的老照片终于再次开放了。
由于使用mod_rewrite似乎有些问题,我将静态问题统一放在了另一个域名下,但这却引出了一些其他问题。以前写程序的时候没有注意到静态文件的问题,直接将静态文件的位置给写死了,此外还有部分其他问题。不过修正后终于跑起来了。
在经过上次的修正后,依旧存在部分css兼容性的问题。不管了,至少大多页面看上去还是正常的。
http://lzpian.haoluobo.com/
本想将代码先整理下,不过似乎也没多少整理的必要。为项目新添加了netbeans的项目配置文件,这样使用netbeans的用户也可以方便的打开工程了。另外还做了个简单的视频演示,空间太烂,似乎要花挺久才能下载完。
项目地址:http://code.google.com/p/springside2vik/
视频演示:http://vik.haoluobo.com/static/springside2vik/springside2vik.htm