Trade Off

supercalifragilisticexpialidocious

Iphone模拟器和sqlite的问题

最近和sqlite打交道比较频繁,感觉很别扭,可能是因为数据库的操作都在模拟器上测试的缘故吧,有几次查看数据库的内容总是没有结果,过一段时间就好了,我现在只能怀疑是模拟器搞的鬼。以后再弄数据库之前应该把模拟器中的程序删掉,重新传入数据。

今天update进去信息,总是没发现数据库更新,怀疑是忘记commit,查看一下FMDB的使用方法,确实有commit一说,而我在看国内某博客写的使用教程时发现他就是随意的update和insert,殊不知这些都需要commit呀!在update和insert代码前后需要加入

1
2
3
[db beginTransaction];
[db commit];

我用的Objective-C。

然而即便是这样,更新了数据库后再查询,确实数据被更改了,但我重新在模拟器中运行程序时候又恢复成了以前的值。偶然在模拟器中打开了程序而不是用xcode运行程序,数据竟然被永久更新了。

所以,以后测试update的时候,前后对比应该只在模拟器中看,如果再用xcode启动,会把原来的数据传入模拟器,这样你就看不到效果了。

惨痛的Box2d经验

说来也可笑,Box2d中有各种各样的Shape,有多边形,矩形,圆形。我就是在用圆形的时候遇到的这样的问题:需要设置圆形的半径,我就用了这样的表达式:26 / PTM_RADIO,后面的是一个宏定义,表示拿多少像素和box2d中的米作为兑换。我这样设置后总看着圆形很不正常,半径不对,而且落到底边也不弹起来,为此还查找了API、Google等地方,看着别人的代码都没问题,就是自己的不正常。

最终还是解决了这样的问题,真羞愧,原来半径需要一个float的值,但我的表达式算出来的应该是int,不过我也曾经写过 float radius = 26 / PTM_RADIO这样的,再把radius给半径,依然无果,感觉即便是类型不对也应该自动转换过去吧,没想到这里还就是不行了。

可恶的!

26.0 / PTM_RADIO

Box2d的简单使用

真不太想写,因为写这篇日志应该比写一个程序都要复杂。

我介绍的是box2d引擎在iphone上的使用方法,网上也有不少介绍的,我再简单啰嗦一番:

首先我们需要一个物理世界:b2world *world;在世界中创造各种各样的body,当然这些body都是刚体,如同经济学中的刚性需求那样,这里值得是形状不会被压扁的坚固物体。这些body默认在实例化后是静态的,除非你明显得把他们的type参数改成b2_dynamicBody,他们就能参与物理运动了。你可以给他们加入密度、弹性、摩擦等参数。这些都是每个body的属性,而这些body是需要刚刚的world创建的,而创建的函数需要一个配置单,就是一个结构体而已。

body出现之后你还不能看到,因为还需要另外的两个重要性质:fixture和shape,这里的shape有两种,一个是多边形,一个是圆形;创建shape后定义一些参数,然后把这个对象传递给fixture的对象,fixture被我叫做材质,刚才介绍的密度、弹性、摩擦等属性就是在这里定义的。当然,fixture有个shape属性,把刚刚实例化的shape对象给他即可。最后用body对象的CreateFixture函数生成fixture。这样应该就能看到你创建的物理实体了。

下面介绍一些刚刚遗漏的概念,在这个物理世界中,我们需要定义一个重要的量——重力,我们所有创建的物理实体都将按照这个重力的方向移动,而这里的重力实际上指的是一个向量,比如说是(0,-10),这样就会向着y轴-10的方向移动,而负坐标是y轴向下的,刚刚实验过,如果用(0,-100)的话,物体下移的速度会比(0,-10)的快很多,这也很明显。

另一个有意义的概念就是休眠了,其实这是创建“世界”的又一个参数,意思是如果有物体到达了无法移动的地方,比如边界,或者说出去了边界,引擎应该就不再计算它的一些数据了,这理所应当,怎么还需要解释呢?我们当然希望引擎能够把主要的计算力量给予需要的物理实体。

上面提到了一个区域的概念,是的,我们应该划定一个区域,在这个区域中的物体参与物理运算,外面的就不再参与了,但这里定义一个区域也是用了向量的方法,而且这个区域也算作一个body,有些难以理解。目前掌握得不好,就不再详述了。

用python处理词汇

要整理一些词汇,并且还要给每个词汇编码,我把所有的词汇分割称了独立的汉字,再把这些汉字压缩,去掉重复的汉字,最后把这些汉字导入数据库,得到了每个汉字的id,把这些id组合起来作为词的编码,这样还算是好用吧。

用python写了7个脚本来做这些工作,最后得到了近7万条记录,包括单独的字和一些词。因为要用来做iphone应用,所以数据库用的是sqlite,大约4MB的数据,看来这些数据已经很够用了吧。

代码实在不太美观,所幸就不粘贴了吧。

哦,对了,在收集资料过程中,找到了一个用mdb包装的成语数据库,可惜mac下没有很好的浏览工具,就找找看有没有转换工具,在GoogleCode上找到了一个mdb转sqlite的工具,用java写的,下载下来后用了一下,出了一个warning,不过没有影响使用。很不错,感谢一下:http://code.google.com/p/mdb-sqlite/

Nginx下的location配置

原来的location只是处理了“/”的情况,结果访问一个目录,即使此目录下有index.html也不会成功显示,于是改成了这样:

1
2
3
4
location ~.*\.(php|php5)?$
{
    处理php
}

这样之后,发现直接访问目录或者域名的时候不能正常显示了,必须跟上index.php这样的才可以。

最终改成这样,解决了问题:

1
2
3
4
5
6
7
location / {
               root html;
               index index.html index.php;
}
location ~.*\.(php|php5)?$ {
处理php
}

Git的导出功能

用git管理项目的优势大家可能都看了许久了,我也是因为如此才用了git而不是svn、cvs这些。其实我是挺喜欢喜新厌旧的,因为新东西的出现并流行一定是比原来的有所突破,并且大多数人喜欢这种变革,所以为何不喜欢呢?

用git管理项目不可避免要遇到导出功能,在svn和cvs上应该叫export功能,git上的这个功能似乎没找到,要这样做:先打包,再解压到一个地方去。还能接受吧。

1
git-archive --prefix=map/ master | tar -x -C ../map_e/

稍微解释一下,prefix指明了用哪个仓库,后面的master应该就是branch的名称了,然后把这些传递给了tar,因为不指明–format的时候默认用了tar方式打包,所以这里传递给tar解压到上层目录的map_e中,当然实际工作可以解压到生产服务器上去。

最好在include_path中加上根

刚刚用了下typecho博客插件——友情链接来添加一个友情链接,但发现很多php文件找不到了,很奇怪,以前是可以的,看到warning中的信息,有个include_path的相关东西,看看里面提到的路径是不是有需要的文件,结果没有,而在其中路径的下一级目录下有,这就怪了。

Google说最好把include_path写成"./“。是不是这样就是自动便利所有的内容了?我猜是的!当前的include_path中又pear的路径,我就先不删除了,linux系统下用冒号分隔各个路径,在前面加上一个点即可。

重启php,再次访问,恢复正常!

简要写写python的file中的tell和seek

对于一个file,调用tell()能够知道现在的文件位置。seek()是改变文件位置。 比如文件中有3行句子,readline后位置就到了第一行的最后,再readline就到了第二行的最后,readline后我调用了tell,看到的结果就是这样的。输出完tell()我又使用了seek(0),这样文件位置就回到开头了,下次再调用readline就会输出原来第一行的内容了,这应该是很容易理解的。不明白可以亲自试试。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
from sys import argv

script, input_file = argv

def print_all(f):
   print f.read()

def rewind(f):
   f.seek(0)

def print_a_line(line_count, f):
   print line_count, f.readline()

current_file = open(input_file)

print "First let's print the while file:\n"
print_all(current_file)

print "Now let's rewind, kind of like a tape."
rewind(current_file)

print "Let's print three lines:"

current_line = 1
print_a_line(current_line, current_file)
print "current_pos:%d" % current_file.tell()
rewind(current_file)

current_line += 1
print_a_line(current_line, current_file)
print "current_pos:%d" % current_file.tell()

current_line += 1
print_a_line(current_line, current_file)
print "current_pos:%d" % current_file.tell()

Python中的*和**

在python的函数参数中,可以在变量名称前面加一个或者两个星号代表不一样的变量类型:

在stack overflow上看到有人问这两个的区别了,就转载过来答案吧:

If the form *identifier is present, it is initialized to a tuple receiving any excess positional parameters, defaulting to the empty tuple. If the form **identifier is present, it is initialized to a new dictionary receiving any excess keyword arguments, defaulting to a new empty dictionary.

加一个星号代表这个参数是一个tuple类型;加两个则是一个dictionary类型,很好用。

Python中的%r和%s

我并不想完整地比较这两个替换符号的用处,只是发现了一点,可能以后也会这样用。

%r是原始的输入,如果输入了中文,在输出的时候会出现一些类似unicode的代码;其他的会输出带单引号的内容。

%s就是字符串了,输出就是字符串,如果原始输入是中文,那这里也会输出中文。其他的会输出不带单引号的字符串内容。