Thursday, November 12, 2009

javascript的var关键字

var name = 'jessinio';
function foo() {
    alert(name);
    name = 'nio';
};

foo();
alert(name);

与其实语言对比, 上面的代码很容易理解: 就是alert一次, 再修改函数外面name变量的值, 这个值被称为全局变量. 在js中不需要global关键字来声明, 当如果这样呢:
var name = 'jessinio';
function foo() {
    alert(name);
    var name = 'nio';
};

foo();
alert(name);

多了红色的var . 比如python:
name = 'jessinio'
def foo():
    print name
    name = ""
foo()
 * 将会出错!

根据学习. js中的var这样:
1. 代码块中的var将使变量的作用范围局限于块中
2. js的全局变量说穿了就是window对象的属性. 例如:
var myfunc = function (){ my = 'global variable scope'};
myfunc()
alert(window.my);
* 增加global变量就是为window增加属性

什么是全局变量?

全局是一个范围, 这个早已经解理, 但是这个范围到底有多大?

就像我们的世界一样: 宇宙外面是什么? 全局包不包括宇宙外面?

只能说: global是相对的.
在python里, 这方面的API:
globals()
    globals() -> dictionary
    Return the dictionary containing the current scope's global variables.
locals()
Update and return a dictionary representing the current local symbol table.

存在run.py文件, 内容如下:
import a.am
a.am.foo()

这里存在四个scope区域:
1. run.py的scope
2. package a的scope
3. module am的scope
4. foo函数的scope

现在的问题是: 不同的scope中使用global声明和修改变量的值后是否会对其它scope产生影响

1. module中的function不会对引用它的scope产生影响 , 只会对module scope产生影响
在run.py文件中调用foo函数, foo函数中:
global name
name = "function set!"
结果发现module am的scope内的name变量变化. 这说明: function中的global声明和修改变量的值会影响到module的情况

2. package中的function不会对引用它的scope产生影响
在run.py中存在语句import a, 其中a/__init__.py的内容:
global name
name = '__init__.py set!'
结果在run.py中的scope没有发现. 这说明: package中的global声明和修改变量的值不会影响到引用它的scope
* 真实情况是: package中的function只是修改了__init__.py的scope. 这与(1)的情况是相同的


python中, 每个*.py都是一个module. package为组织module的一个对象, 说穿了package也为一个module, 例如:
# 主运行文件
jessinio@niolaptop /tmp/test $ cat use.py

import a.am
a.foo()
a.am.foo()
# pacakge的__init__.py文件
jessinio@niolaptop /tmp/test $ cat a/__init__.py
import pprint
def foo():
    print "package funcion"
# module文件
jessinio@niolaptop /tmp/test $ cat a/am.py
def foo():
    print "module am function"
# package这个绝对算是module!
jessinio@niolaptop /tmp/test $ python use.py
package funcion
module am function

在import入package下的module时, package这个"module" 也被import了! 这绝对叫到: 不正当捆绑型消费

每个python文件都会有下面的属性:
'__builtins__'
'__doc__'
'__file__'
'__name__'
'__package__'

package的__init__.py还会多一个属性:
'__path__'

Saturday, November 7, 2009

gentoo QA

刚开始, update world的时间, 也是来了一个QA打字的note. 没有注意, 然后把pidgin使用的eds USE标志去掉了.
因为这个USE需要evolution的. 就是在满足它的时候出了错误, 还正也不想安装evolution. 干脆去了它.

但是make了一小会, 又出了大致的错. 这一下提起注意, 因为错误大致有QA:
 * QA Notice: Package has poor programming practices which may compile
 *            fine but exhibit random runtime failures.
 * auevents.c:149: warning: incompatible implicit declaration of built-in function ‘free’
 * auevents.c:249: warning: incompatible implicit declaration of built-in function ‘free’
 * connection.c:569: warning: incompatible implicit declaration of built-in function ‘free’
 * connection.c:592: warning: incompatible implicit declaration of built-in function ‘free’

QA是什么?

G了一下, 得这个URL: http://www.gentoo.org/proj/en/qa/

难度是gentoo对包的要求过高了? 查了一把, 没有查到相关的配置

算了, 代码问题就不理会. 不然这级至少要半年才能升.

我搞不过, 还躲不过? 把这个包去掉再说!

BTW:: 每次升到QT就是烦!! 什么时候把QT也干废!

Wednesday, October 28, 2009

代码与API文档

从代码中直接提出API文档, 是一件令人高兴的事. 自己辛苦写的代码, 终于有了给人看得懂的文档了(虽然代码是ugly的)
python还方面的工具也很多的. epydoc就是送的一个小工具(我也不知道什么时候被安装入系统的).

从代码里取出API文档, 是原于一个叫documentation strings的东西. 在python里, 有这种东西的对象如下:
1. modules
2 functions
3 classes
4 methods

在哪里定义docstrings呢?
An object's docsting is defined by including a string constant as the first
statement in the object's definition.
看来, 第一个有效的语句, 并且是string型的, 就是叫docstring
function, classes, method比较好理解, 下面两个特殊一点的对象:
1. 在module中, 在py文件的除了"#"开始的行外, 第一个字符串语句
2. 在package中, docstring在于__init__.py文件中, 情况与module相同

docstring只是第一步. 需要进一步细分文档内容, 比如, 描述一个function的用途, 参数和返回情况. 这时需要在docstring中使用一种叫fields的东西, 如下URL:
* http://epydoc.sourceforge.net/manual-fields.html

如果想对docstring样式控制的话, 还有此功能的:
* http://epydoc.sourceforge.net/manual-epytext.html

BTW: docstring里样式控制就太花了. 加点缩进还是可以忍受的

Tuesday, October 27, 2009

django的ORM操作

不可否认, django的文档写的很好, 也很多文档.


对于本人还是那句话: 如果使用文字不能把一件事物清楚地描述出来的话, 那么你对这件事物还是不清晰 .  (^_^)


ORM类实例对象的创建

1. 使用类的__new__方法

2. 使用类Manager.create方法


两个类:

class Musician(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    instrument = models.CharField(max_length=100)

class Album(models.Model):
    artist = models.ForeignKey(Musician)
    name = models.CharField(max_length=100)
    release_date = models.DateField()
    num_stars = models.IntegerField()


创建对象:

1. 使用类的__new__方法:

In [6]: m = Musician(first_name='firename', last_name='lastname', instrument="something")
In [7]: m.id

这时, 新创建的对象是没有id的. 也就是还没有数据库的记录. 还需要使用方法把数据存在到数据库中:

In [8]: m.save()
In [9]: m.id
Out[9]: 2L

2. 使用类的Manager.creater方法:

In [4]: m = Musician.objects.create(first_name='firename', last_name='lastname', instrument="something")
In [5]: m.id
Out[5]: 3L

这时, 数据已经被添加到数据库表, 不用调用save方法


任何model类实例对象都有这两种方法创建.

ManyToOne Field添加引用实例

Album与Mussician的关系是"多对一", Album创建实例时多了一个条件: Album的__new__和Manager.create会检查artist参数是不是Musician的实例:

__new__方法:

In [12]: a = Album(artist=2, name='album name', release_date=datetime.datetime.now(), num_stars=10)

ValueError: Cannot assign "2": "Album.artist" must be a "Musician" instance.

Manager.create方法:

In [13]: a = Album.objects.create(artist=2, name='album name', release_date=datetime.datetime.now(), num_stars=10)
ValueError: Cannot assign "2": "Album.artist" must be a "Musician" instance.

* 传个与primary key相同的数字还是出错

需要在artist参数位置传入一个指定的实例:

步骤1: 使用Musician的__new__或者Manager.create创建Musician对象:

m = Musician(first_name='firename', last_name='lastname', instrument="something")

m.save() # 一定要被存在在数据库中才能被Album的创建方法正常使用, 则否出错.

a = Album(artist=m, name='album name', release_date=datetime.datetime.now(), num_stars=10)

a.save()


如果m不使用save()的情况:

In [27]: m = Musician(first_name='firename', last_name='lastname', instrument="something")
In [28]: a = Album(artist=m, name='album name', release_date=datetime.datetime.now(), num_stars=10)
In [29]: a.save()
IntegrityError: (1048, "Column 'artist_id' cannot be null")

出错. 说artist_id为null


使用对象:

有两个方向: 1. 从Foreign端; 2. 从被Foreign端

1. 从Foreign端

In [19]: a = Album.objects.get(pk=1)
In [20]: a.artist.id
Out[20]: 4L

In [22]: a.artist.first_name
Out[22]: u'firename'
这种引用方法很pythonic


2. 从被Foreign端


这时候被称为: The “other side” of a ForeignKey relation. 如果一个model类被其它类通过foreign key引用的话. 那么, 在被引用

的类和这个类的实例中, 会多一个属性:

In [61]: type Musician.album_set
-------> type(Musician.album_set )
Out[61]: <class 'django.db.models.fields.related.ForeignRelatedObjectsDescriptor'>
In [62]: m = Musician.objects.get(pk=1)
In [63]: type m.album_set
-------> type(m.album_set )
Out[63]: <class 'django.db.models.fields.related.RelatedManager'>
在django文档中有这样一句话:

Following relationships "backward"


If a model has a ForeignKey, instances of the foreign-key model will have
access to a Manager that returns all instances of the first model. By
default, this Manager is named FOO_set, where FOO is the source
model name, lowercased. This Manager returns QuerySets, which can be
filtered and manipulated as described in the "Retrieving objects"


作用就是能通过此方法找到一个对象都被哪些对象引用


# 下面是从album实例找到引用的musician实例

In [64]: a = Album.objects.get(pk=1)
In [65]: a.id
Out[65]: 1L

In [67]: a.artist.id
Out[67]: 4L

# 下面是从musician实例找到被哪个album实例引用了

In [68]: m = Musician.objects.get(pk=4)
In [70]: a_set = m.album_set.all()
In [71]: a_set.count()
Out[71]: 1
In [72]: a = a_set[0]
In [73]: a.id
Out[73]: 1L

蓝色的部分都是一样的, 表示是同一个album实例

ManyToMany Field添加引用实例

class Domain(models.Model):
    name = models.CharField(max_length=128)
    is_singular = models.IntegerField()
    description = models.CharField(max_length=32, default="")
    object = models.ManyToManyField("Object")

class Object(models.Model):
    name = models.CharField(max_length=128)
    description = models.CharField(max_length=32, default="")

ManyToMany字段是可以引用(foreign)多个实例的. 这通过ManyToMany Field的add方法实例:
 In [2]: domain = Domain(name = 'china', is_singular=1)
In [3]: domain.object.add
ValueError: 'Domain' instance needs to have a primary key value before a many-to-many relationship can be used.
In [5]: domain.object.add
Out[5]: <bound method ManyRelatedManager.add of <django.db.models.fields.related.ManyRelatedManager object at 0x9fa82ec>>
可以看出, ManyToMany Field的add方法是需要在save后才有的.

下面为ManyToMany Field增加引用实例:
In [6]: obj = Mod.Object(name="object1")
In [7]: domain.object.add(obj)
IntegrityError: (1048, "Column 'object_id' cannot be null")
* 与Foreign Field是一样的, 都是需要被引用的对象先存在于数据库表中!
In [8]: obj.save()
In [9]: domain.object.add(obj)
In [10]: domain.save()

* 调用obj.save后, 才成功添加引用实例!
还是可以引用多个实例的:
In [11]: obj = Object(name="object2")
In [12]: obj.save()
In [13]: domain.object.add(obj)
In [14]: domain.save()
* 这么多个save(), 是因为底层还是关系型数据库, 每一次save就对应着一次insert或者是update

通过through参数, 使用定制义的中间表, 此后, ManyToMany Field没有了add方法!

新的模型如下:
class Domain(models.Model):
    name = models.CharField(max_length=128)
    is_singular = models.IntegerField()
    description = models.CharField(max_length=32, default="")
    object = models.ManyToManyField("Object", through="DomainObject")

class Object(models.Model):
    name = models.CharField(max_length=128)
    description = models.CharField(max_length=32, default="")

class DomainObject(models.Model):
    domain = models.ForeignKey("Domain")
    object = models.ForeignKey("Object")

# 找一找ManyToMany Field的add方法:
In [2]: domain = Mod.Domain(name = 'china', is_singular=1)
In [3]: domain.save()
In [4]: domain.add
AttributeError: 'Domain' object has no attribute 'add'
* 被掩了!
为ManyToMany Field添加引用实例需要使用如下方法:
In [6]: domain
Out[6]: <Domain: Domain object>
In [7]: obj
Out[7]: <Object: Object object>
In [8]: domain_object = Mod.DomainObject.objects.create(domain=domain, object=obj)
* 这里的Manager.create方法可以类的__new__方法
这是显式使用了中间表对应的类来生成映射关系.

使用对象:

和上面的ManyToOne情况一样, 有两个方向: 1. 从Foreign端; 2. 从被Foreign端

1. 从Foreign端
In [23]: domain.object
Out[23]: <django.db.models.fields.related.ManyRelatedManager object at 0x9fa802c>
为一个Manager对象!
In [24]: objs = domain.object.all()
In [27]: for item in objs:
   ....:     print item.id
1
2
可见, 这时间是需要指定select条件才能取回自己想要的对象

2. 从被Foreign端
In [28]: obj = domain.object.all()[0]
In [29]: obj.id
Out[29]: 1L
In [30]: domain.id
Out[30]: 1L
可见, ID为1的domain引用了ID为1的object, 反过来找:
In [35]: obj = Object.objects.get(pk=1)
In [39]: domain = obj.domain_set.get(pk=1)
In [40]: domain.id
Out[40]: 1L

改变RelatedManager的名字

class Musician(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    instrument = models.CharField(max_length=100)

class Album(models.Model):
    artist = models.ForeignKey(Musician, related_name="Musician_set")
    name = models.CharField(max_length=100)
    release_date = models.DateField()
    num_stars = models.IntegerField()

多了红色代码, 然后:
In [7]: m = Musician(first_name='first_name', last_name='last_name', instrument='instrument')
In [8]: m.Musician_set
Out[8]: <django.db.models.fields.related.RelatedManager object at 0x8de220c>


映射与primary key, foreign key

一对多, 多对多, 多对一, 一对一. 这是什么?

这种是什么关系? 在初中数学中有一种叫: 映射 的概念.

定义:设A和B是两个非空集合,如果按照某种对应关系f,对于集合A中的任何一个元素,在集合B中都存在唯一的一个元素与之对应,那么,这样的对应(包括集合A,B,以及集合A到集合B的对应关系f)叫做集合A到集合B的映射(Mapping),记作f:A→B。

这个"对应关系f"又是一个忽悠级的概念. 又如, money与owner就是一种"对应关系". 那么girls与me有没有关系呢? 当然了! 当me为mine时就很明显了!

重要的几句话:
1. 映射,或者射影,在数学及相关的领域经常等同于函数
 * f就是这个函数. A的与B只不过是stdout与stdin罢了
2. 对应的唯一性:定义域中的一个元素只能与映射值域中的一个元素对应
 * 如图:
图1不是中的集合A到集合B不形成映射! 因为这不是唯一性!

那么为什么在数据库中常出现"一对多"的情况呢?
映射是有方向的, 上面的图(1)如果方向从B到A, 使用f = N^2这个法则的话. 就形成了集合B到集合A的映射. 就是说"一对多"的另一个方向是"多对一"

"多对多"是怎么解释?
从django的ORM实现ManyToMany关系类型就大概知道了:

左边的图是"多对多"的情况, 等价于右边的图. 增加一个中间集合, 关系被分成两个大圆上. 结果是: "一对多 => 多对一".

所以, 映射有二种:
1. 一对一
2. 一对多

primary key 和 foreign key又是何方神圣?

1. primary key就是一个集合中, 为每个元素分配一个唯一的序号. f(集合, pk)一定可以得到唯一的元素
2. foreign key就是当某一集合的元素的primary key序号在另一集合中作为元素值时对这个序号(数字)的称呼. 与上面一样, f(集合, pk)也是可以得到唯一的元素. 如果得到的元素又是另一个集合的primary key呢? 于是: f2(集合2, f1(集合, pk))也是有唯一的元素的. 这样就可以把N个集合的关系表达出来.

primary key应该放在哪个集合中?

1. 对于"一对一"的情况, 放在哪个集合都是可以形成映射的

2. 对于"一对多"的情况. primary key应该存在"多"的一端.

数据库技术中, 使用primary key 与 forgein key概念来完成了表与表的相引用, 也增加了一些约束, 使key(为某一数字)拥有更多功能. 例如django文档这样写的:
When Django deletes an object, it emulates the behavior of the SQL
constraint ON DELETE CASCADE -- in other words, any objects which
had foreign keys pointing at the object to be deleted will be deleted
along with it.

虽然foreign key也是一个数字, 但给以它更多的意义.




BTW: 找数学知识文档没有经难. 比较难找.
http://baike.baidu.com/view/21249.htm

Thursday, October 22, 2009

screen的同类产品

一个名为tmux的软件, 功能与screen类似, 号称是BSD协议的GNU screen

这里有介绍: http://niallohiggins.com/2009/06/04/tmux-a-bsd-alternative-to-gnu-screen/


随便找个地方记录一下自己的screen配置, 方便日后快速找回:

escape ^Ss
bind j focus down
bind k focus up
bind t focus top
bind b focus bottom
# 删除这几个
bind ^k
bind 'K'