Open source for open soul ;;

九月 04, 2008

用 jQuery 将填表单时的 enter 模拟为 tab 键

var input =  $("input");
input.keydown(function(evt) {
    if(evt.keyCode==13)  // 回车
    {
        var inext = input.index(this)+1;
        var next = input[inext]?input[inext]:$("input:first");  // 移到下一个input,如果已经是最后一个则跳到第一个input
        next.focus();
        next.select();
        return false;   // 返回false使回车失效
     }
});

八月 07, 2008

对 Google App Engine 中 datastore 的理解

GAE的datastore中,除了一般one-many, many-many的orm关系外
还引入了entities group,key_name, parent等概念(其实我对orm也只是知道点皮毛而已,所以不知道这点是不是GAE的独创)

原来一直觉得这些东西很多余,理解不了
但当使用 Transaction 读写数据时才发现只有同一entities group的entity才可以在一个事务中操作,也就是说所有在一个事务中操作的entity都可以追溯到同一个parent,在datastore关系中,被称为 root

明白了这点,要使用事务,就需要将原来一整套仅仅根据one-many, many-many关系建立的entity加入自己的parent关系(parent只能在entity未提交到datastore前建立,不管有没有制定,entity一旦提交就无法修改)

在建立entities group时,key_name是一个很有用的属性,可以利用key_name建立一个unique的属性,在entities group中快速定位到想要的entity

为了方便使用entities group,我定义了一个Person:
class Person(db.Model):
user = db.UserProperty()
displayName = db.StringProperty()
lastVisted = db.DateTimeProperty(auto_now=True)

在用户登录后,使用
Person.get_or_insert(key_name=user.nickname(), user=user)
为新用户创建属于自己的Person实体,为老用户获取Person实体
然后使用这个entity作为其他与该用户相关的entity的root,就享受GAE datastore的事务处理了

八月 01, 2008

几个 GAE 特有的特性

关于 GQL

  1. 类似 WHERE .. IN 的sql只能通过 GqlQuery 实现
  2. GqlQuery 通过多次查询遍历
  3. 如果查询引用,应该使用 key 而不是实体的 list

待补充

七月 23, 2008

lightbox 效果的实现原理

用一个单独的 div 作为 overlay
这个overlay 有三个主要的属性

  1. 大于页面文件的width和height
  2. 合适的透明度(opacity)
  3. display:none;
在激活时,去掉display:none,这个overlay就成为了新页面的background

六月 06, 2007

其实还是用到了matplot
主要是自己对绘图的算法不是很熟,而matplot的绘图效果一向比较欣赏

这个方法
需要自己build scipy把delaunay模块包含进去
按照windows下的安装指南
手动build scipy还需要先安装ATLAS (3.6.0)/LAPACK库,而我用cygwin build的ATLAS没有任何作用-____-
还好在不考虑性能损失的情况下还可以使用LAPACK/BLAS的源码直接build

然后再次发现原来我下的0.4.8的scipy不包含delaunay....
残念...安装TortoiseSVN,go bed
明天用svn的scipy继续吧````忙乱的一天呀

更新:
numpy编译不成功
于是用了wiki 上另外一个方法 griddata
下载后先编译其中的c源码
setup.py build --compiler=mingw32 bdist_wininst
需要mingw或者cygwin,并且要把gcc的路径加入到环境变量中(或者直接在cygwin中编译)
然后运行
setup.py install
就安装成功了

之后使用griddata提供的test.py测试一下好了

现在就可以用griddata将离散的值进行natural neighbor interpolation
并用matplotlib显示出来了~
效果不错:)


接下来就是一些美化工作了
全都要靠自己了





十月 08, 2006

The ABC of Blogger Template Tag

国庆几天看了很多blogger模版修改的trick和tip,但看得越多就觉得越乱。只能是依葫芦画瓢,缺少自己的想法和思路。加上一直想加上一个AJAX的评论功能,所以今天下载了自己的Template开始好好研究。

总的来说,Blogger的Template也就是一种标示语言,在

中已经说得很清楚了。

但是有几个小地方还是需要特别注意一下的;)

首先, b:sectionb:widget 是定义页面的最基本元素(tag),其中 b:section 的子元素只能是 b:widget

其次,<b:widget>的使用形如:

<b:widget id="myList" type='ListView' pageType="all" locked="no" title="My Favorite Things"/>

其中最有意思的就是 pageType 属性了,通过设置成不同的值: "all," "archive," "main," or "item,",可以指定这个widget在所有页面,存档页面,首页或单独的文章页面显示(暂时有问题,不能在模版中使用)。

之后,b:widget下面的元素就是 b:includable b:include

b:includableb:include 的关系就像C语言中的函数声明与函数的调用。首先,每个 b:widget 里面都需要一个main主函数:

<b:includable id='main' var='this'>
[content]
</b:includable>

id相当于函数名,而var则是变量。你还可以用不同的id声明其他 b:includable ,并通过

<b:include name='id_other' data='var_other'/>

调用 b:includable ,并通过data属性传递参数。在其内部则通过 data: 使用参数,如:


data:var_other.title


除了"main",可以使用 b:include 调用同一 section 内的任意 b:includable 。而每个 :widget 自动调用其中的"main" b:includable


最后,不同的widget还有不同的 data: ,可以在 Layouts Data Tags 找到不同 widget 对应的 data: 列表,列表里面的 data: 都是直接在"main" b:includable中可见的。也就是对"main" b:includable来说,即使没有申明var属性,仍然可以直接得到widget传递的参数


BLogger的模版语言还有其他的tag, 比如 b:loop, b:if, b:else, expr:。主要用于控制flow,用法还算简单,具体还可以参考 ecmanaut: Blogger beta templates

九月 18, 2006

ActiveMapper in SQLAlchemy

ActiveMapper 是SA里面很酷的extension
简化了SA先定义表再mapping的繁琐,又能充分利用SA mapper 的特性

下面是ActiveMapper最基础的用法。


from sqlalchemy.ext.activemapper import ActiveMapper, column, \
objectstore, metadata, one_to_many, one_to_one, many_to_many

metadata.connect('sqlite:///../idtest.db')
metadata.engine.echo = True

user_group = Table("user_group", metadata,
Column("user_id", Integer,
ForeignKey("tg_user.user_id"),
primary_key=True),
Column("group_id", Integer,
ForeignKey("tg_group.group_id"),
primary_key=True))

class Group(ActiveMapper):
class mapping:
__table__="tg_group"
group_id = column(Integer, primary_key=True)
group_name = column(Unicode(16), unique=True)
created = column(DateTime, default=datetime.now)

class User(ActiveMapper):
class mapping:
__table__="tg_user"
user_id = column(Integer, primary_key=True)
user_name = column(Unicode(16), unique=True)
password = column(Unicode(40))
created = column(DateTime, default=datetime.now)
groups = many_to_many("Group", user_group, backref="users")

u = User()
u.user_name = 'test'
g = Group()
g.group_name = 'admin'
g.users.append(u)
objectstore.flush()


在mapper的使用上基本上与SA一般的用法没什么差别.
要注意的就是在申明class的时候,使用one_to_many, many_to_many这些函数来定义各个表之间的关系。
而与数据库的连接,则用sqlalchemy下面的 metadata, objectstore来进行
metadata.connect()连接数据库
objectstore.flush()将对对象的修改提交到数据库

ps:
现在activemapper有一个小bug就是,如果两个表是多对多的关系,
那么不能在两个class下面同时申明many_to_many,
而只要给many_to_many一个backref参数,这个属性就会自动添加到对应的class下

Beautiful Soup with Chinese.

BS对unicode文档处理的基本流程是:

  • 首先判断 BeautifulSoup(html, fromEncoding=encoding)中指定encoding
  • 如果没有指定 encoding,则调用 chardet (如果已安装),或是内置的unicodeDammit尝试探测编码
  • 最后将编码转换为unicode,进行相关的解析
而输出字符的流程更为简单:
  • 通过__str__(coding) 或 renderContents(coding) 指定输出的编码:encode(coding)
  • 如果coding没有指定,则以 'utf-8' 作为默认输出
所以,若是处理 "gbk" 的文档,需要这样使用


soup = BeautifulSoup(html_str, fromEncoding="gbk")
print soup.__str__('gbk')
# or
print soup.__str__().decode('utf-8')