Showing posts with label 编程. Show all posts
Showing posts with label 编程. Show all posts

Dec 16, 2008

《重构》1-4章_基础

上个礼拜拿到了《重构》,读了前面的几章。还是蛮有意思的一本书,作者很幽默,译的也不错,只是价钱贵了点,有那么一点心疼。经典的书大多读起来不轻松,读快了啥也学不到,可有些经典的书读着有趣,随便翻翻有意无意间就会有比较大的收获,比如《代码大全》、《重构》等等。道理简单而实用,例子也恰到好处,加之文章穿插的点点幽默,实在是大快人心。

“记性好忘性大,故凡有所的必记诸文字”,译者熊节这话说得贴切。今天拿到的Maxtor的移动硬盘,广告居然叫“Save your life”。很好。不时时记录时时备份时时回顾,像我这等愚笨之人很快就会忘记生活了啥,这不能不说是一件可悲之事。

http://old.blog.edu.cn/user2/26669/archives/2007/1753406.shtml 上发现了《重构》的笔记,我就直接厚颜无耻得拿来,然后再稍稍加些东西吧。

译序 --熊节
快速迭代&RAD --> crack的问题解决方式,在混沌的循环往复中实现需求--解构的美。
软件开发的理想国--在设计前期使用模式往往导致过度工程
重构--空气和水

前言

设计不再是一切动作的前提,而是在整个开发过程中逐渐浮现出来。
重构:有纪律,经过训练的,有条不紊。
聚沙成塔,从根本上改变设计

第一章、重构:第一个案例


例子:影片出租店用的程序。操作者告诉程序:顾客租了哪些影片、租期,程序就根据租期和影片类型计算费用;还要为常客计算点数。点数的计算与是否为新片有关系。程序为每次租用打印报表。

措施:同一段代码不要出现两次,应该用函数来定义。否则将来还要修改多处,容易引进错误。

需求变化1:用html方式输出报表。
需求变化2:要改变电影的分类方式,当然会影响收费和点数的计算,但是具体方案还没确定。

经验:不论用户提出什么方案,你唯一能得到的保证就是用户会在6个月内修改。
(这条经验很好玩,相当于说,你根本无法保证用户的需求不变化,唯一能得到的保证就是用户需求一定会变化。)
如果你发现自己需要为程序添加一个特性,但代码结构使你无法方便地那么做,则先重构再添加特性

重构第一步:为即将重构的代码建立测试环境。这是永远的第一步。
修改必须依赖测试,否则很容易进入新的bug,而且非常难debug。
重构之前,首先检验自己是否有一套可靠的测试机制,这些测试机制必须有自我检验能力。

措施:修改长的离谱的函数,并把函数移动到合适的class中去。
措施:修改变量的名字,使程序更可读。

note:任何一个傻瓜都可以写出计算机可以理解的代码。只有写出人类容易理解的代码,才是优秀的程序员。

阅读代码的时候,我经常进行重构。这样我就不断地把我的理解嵌入到代码中,才不会遗忘我曾经理解的东西。

如果一个类成员函数没有用到所在类的数据成员,则要考虑这个函数是否放错了位置。

尽量消除临时变量。临时变量往往形成问题,可能导致大量参数传来传去。在长长的函数中不易读。当然会付出性能上的代价。
作者的意思是,如果临时变量需要好几行来计算得到,就把临时变量的计算抽取为函数,称为query method。

重构以微小的步伐修改程序,及时发现。

运用多态取代switch、if/else。

一部影片可以在生命周期内修改自己的分类,但是一个对象却不能在生命周期内修改自己的类型(class)。--解决办法:state pattern
建立price类以及三个子类,与价格相关的代码移动到price相关类中。movie中设置一个price类型的成员对象。
price类中设置一个虚函数getprice,再实现一个默认的getpoints,让newprice子类去覆盖它。
把类型相关的代码用state/strategy代替。

本章总结

extract method: 把长函数中的某部分抽取出来。把临时变量的计算抽取为函数(query method)。
move method: 看method使用哪个类的信息,就移动到哪个类中去。
replace conditional with polymorphism
self encapsulate filed ?这个是啥?
replace type code with state/strategy

重构的节奏:测试、小修改、测试、小修改。。。
重构后的程序风格将十分不同于过程化的风格。

第二章 重构原则

重构定义:对软件内部结构的一种调整,目的是在不改变软件的外部行为的前提下,提高可理解性,降低修改成本。
注意,重构的目的不是提高性能
高效且受控的代码整理模式。
两顶帽子:添加新功能和重构。
开发过程中,需要经常换帽子戴,无论何时,都该清楚你戴的是哪顶帽子,而且不能同时戴两顶帽子。

为什么要重构?
1、改进软件设计。重构就是要让所有代码回到应该在的位置。重构还可以消除重复代码。代码结构的流失是累积性的。
2、使软件更容易理解。修改代码,让代码反映我的意图。重构可以帮助你看到你以前看不到的设计层面的东西。重构带你到更高的理解层次上。
3、帮助你debug。弄清楚程序结构的同时,也很清楚地看到自己所做的一些假设。做个有着优秀习惯的好程序员。
4、助你提高编程速度。良好设计才是快速开发软件的根本。

重构应该随时随地进行。

三次法则:如果第三次做类似的事情,就应该重构。Three strikes and you refactor.
添加功能时重构
修改错误时重构
复审代码时重构。复审(code review)就是别人看你的代码。
不必想像代码应该是什么,可以看见它是什么样

为什么重构有用?kent beck

重构的方向:容易阅读;消除重复逻辑(代码);新的改动不会危及现有行为;尽可能简单表达条件逻辑。摆脱束缚的道路

间接层和重构 kent beck

间接层是双刃剑,需要更多的管理,难以阅读。但是,间接层的价值是:

1、允许逻辑共享;
2、对“意图”和“实现”分开解释。class和函数的名字可以看作你的意图,其内部代码是其实现。如果class和函数以“更小的意图”来编写,则“实现”更近距离地和“意图”接触。
3、将变化隔离。
4、把条件逻辑用多态来表示,往往能增加清晰度并提高弹性。

如果增加一个异常。。。为了控制这种情况,为一个pakage定义一个super异常,这个packge下的所有异常都继承自它。这样就可以新增异常了。

重构与设计互补。重构降低了预先设计的压力。可以带来更简单的设计。在设计时仍然考虑各种可能的变化和更为灵活的设计,但是要考虑:把一个简单的方案重构为灵活的方案需要多大代价?

教训:哪怕你完全了解系统,也请实际测量它的性能,不要臆测。(或许潜台词是,你也许了解程序的架构和各种细节,但是你不一定了解系统中代码的执行率。)

要想优化性能,必须认真测量。



重构与性能:重构的确会使软件的运行变慢,但它使优化阶段的性能调整更容易。
efficient:高效;effective:有效
首先编写出可调的软件,然后调整它以获得足够的速度。
时间预算法 >> 持续关注发 >> 90%"发现热点,去除热点"

第三章:代码的坏味道

知道How不代表知道When,决定何时重构、何时停止和知道重构机制同样重要。
没有任何知识规矩能比得上一个见识广博者的直觉。

1、重复代码

同一个类里的两个函数有相同的表达式。方法:extract method

两个兄弟子类里含有相同的表达式。方法:对两个类使用extract method,然后使用pull up method,放到父类中。


2、过长函数

现在的编译器优化已经基本消除了函数调用开销。

小函数容易理解。让函数容易理解的关键是,给函数起一个合适的名字。

每当感觉需要用注释说明什么的时候,就把那部分提取成函数,以其用途而不是实现方式命名。

其实关键不在于函数的长度,而在于“做什么”和“如何做”之间的语义距离。

99%的场合下,只需要使用extract method

对于大量的参数,可以引入参数对象;对于临时变量,可以使用query method。

杀手锏:replace method with method object.


3、过大的类

很容易产生代码重复。

产生太多的临时变量。


4、过多的参数

类可以减少参数,因为成员函数需要的很多参数可以在类中找到。


5、发散式变化(divergent change)

当需求变化一点时,一个类需要修改好几个函数,则这个类或许应该被拆成两个类。


6、散弹式修改(shotgun surgery)

当需求变化一点时,需要对多个类做出小修改。应该使用move method和move field把要修改的代码放到一个类中。

原则是:将一起变化的东西放在一块儿。


7、依恋情结(feature envy)


某个函数对某个宿主类以外的类特别依赖。症结往往是数据。extract method , move method


8、数据泥团(data clumps)


常常可以看到:两个类中有一个以上的相同数据成员,许多函数中有相同的参数。这些总在一起出现的数据应该提取为一个类。

更重要的是,可以帮助寻找feature envy。


9、基本类型偏执(primitive obsession)

很多程序员懒得定义一些小类。

你可以定义一些与基本类型差不多的小class,比如字符串、日期、含一个起始值和一个结束值的range class、电话号码等等特殊的字符串。


10、swith

switch的问题在于重复。?

如果要添加一个case子句,很容易出错。


11、平行继承体系

就是两套class有相似的继承体系。当你为一个类增加子类时,必须为另一个类增加一个平行的子类。

shotgun surgery的一种特殊情况。


12、冗余类

对于没用的类、体系结构坚决消除。


13、过多考虑未来不确定的需求


如,看不到用处的扩展性。


14、很少用的数据成员

有的field可能只在极少情况下被使用。可以为这个field及其相关代码extract class。


15、过度耦合的消息链


没懂。也许后面有例子会好一点。


16、中间人


太多的delegation,就产生了中间人。中间人几乎不干实事,应该消除。


17、过分亲密

两个类过于亲密,互相探究彼此的private部分。有很多方法解决这个问题。可以move method,move field,extract class等等。


18、异曲同工的类/函数


两个函数功能一样但是签名不一样。


19、不完美的程序库


如果程序库不满足需求,可以:introduce foreign method, introduce local extension


20、纯粹的数据类


就像java bean?也挺有用的啊

只有fieild和getter setter。应该把调用它的那些代码抽取到这个类中,以隐藏一部分getter/setter


21、拒绝继承

如果子类拒绝继承父类的某些field、某些函数的实现,问题不算很大,甚至可以不用管;但是如果子类拒绝继承父类的接口,这就出现问题了。


22、过多的注释


当你需要撰写注释,请先尝试重构,试着让所有的注释都变得多余。

注释常常把我们带到之前提到的各种smell。如果注释要解释一块代码做了什么,请extract method;如果已经提取出函数但是仍然需要注释,则请rename method;如果需要说明某些入口条件,请引入断言。

注释可以写todo,why。



第四章:构筑测试体系
seft-testing Code
: 确保所有的测试都完全自动化,让它们自己检验自己的测试结果。
极限编程者都是十分专注的测试者。
testing main: 每个Class都需要有一个用于测试的main()
频繁地运行测试,每次编译都把测试考虑进去。
编写测试代码时,先让它们失败--failures <--> errors
bug --> 编写单元测试
编写不完善的测试并实际运行,好过对完美测试的无尽等待。
必然有错 --> 抛出异常

Oct 15, 2008

Learning python 读书笔记 PART 6

PART 6: Classes and OOP
Chapter 19. OOP: The Big Picture
classes: instance factories, data + function
Instances: represent the concrete items in a program's domain
attributes searching at runtime, lower level to higher level
Coding Class Trees
Class C1(C2, C3): multiple inheritance
Attributes --> class  :  assignments made within class statements
Attributes --> instances  :  assignments to self inside class statements
>>> class C1:
    def setname(self, who):
        self.name = who       
>>> I1 = C1()
>>> I1.setname('xyz')
>>> print I1.name
xyz
initialization: def __init()

Chapter 20. Class Coding Basic
Class: namespace, generating multiple objects, namespace inheritance, operator overloading
Module: namespace
Classes VS. Instances
Class objects probide default behavior:
attributes functions --> class <-- a class name
Instance Objects are concrete items:
call a class object like a function makes a new instance object
each instance object inherits class attributes and gets its own namespace
a new attribute can be generated on the instance
Classes are customized by Inheritance
classes and modules:
from module1 import Class1
class Class2(Class1): ...
Classes can intercept Python Operators
def __init__(self, value): ...
def __add__(self, other):
    return ...
def __mul__(self. other):
    self.data = ...

Chapter 21. Class Coding Details
The Class Statement
class <name>(superclass,...):
    data = value
    def method(self, ...):
        ....
Methods
instance.method(args...) == class.method(instance, args ...)
Calling superclass constructors:
class Sub(Super):
    def __init__(self, x):
        Super.__init__(self, x)
        ......
Inheritance
Abstract superclasses:
class Super:
    def method(self): ...
    def delegate(self):
        self.action()
    def action(self):
        assert 0, 'action must be defined!'
Operator Overloading
__init__: Constructor
__del__: destructor
__add__, __radd__, __iadd__: +, right-side + , +=
__or__:  |
__repr__,__str__ : printing
__call__ : X()
__getattr__ : X.a
__setattr__ : X.a = value
__getitem__ : X[key], for loops, in tests
__setitem__ : X[key] = vlaue
__len__
__cmp__, __lt__, __eq__
__iter__
user-defined iterators
def __init__(self, start, stop):
def __iter__(self)
    return self
def next(self)
    ....
__getattr__ and __setattr__ catch attribute references
__getattr__: is not called if Python can find the attribute, used to deal with undefined attributes
__setattr__: if defined, self.attr = value --> self.__setattr__('attr', value)
    self.__dict__['name'] = x
__repr__ VS. __str__
>>>x  :  run __repr__
>>>print x  :  run __str__
add:
>>>x + 1 #__add__
>>>1 + y #__radd__
__call__:  x(attr)
__del__: run automatically when an instance's space is being reclaimed
Namespaces: The Whole Story
instance -- __class__ --> class
class -- __base__ --> higher superclasses

Chapter 22. Designing with Classed
Python and OOP
inheritance polymorphism encapsulation
Overloading by Call Signatures
*class C:
     def meth(self, x): ...    #a
     def meth(self, x, y):...  #b
 a will overwrited
*class C:
     def meth(self, *args):
          if len(args) == 1: ...
*class C:
     def meth(self, x):
          x.operation()
Classed as Records
OOP and Inheritance: "is-a" relationship
OOP and Composition: "has-a" relationship
OOP and Delegation
Multiple Inheritance
search process depth-first all the way to the top
Classes are objects: Generic Object Factories
apply function:
def factory(aClass, *args)
    return apply(aClass, args)
Methods are objects: Bound or Unbound
Unbound: class, no self
object1 = Spam()
t = Spam.doit
t(object1, 'lalal')
bound: instance, self + function pairs
object1 = Spam()
x = object1.doit
x('lalal')
Documentation String Revisited
import docstr
a.__doc__, a.b.__doc__
Class Versus Modules
they are both namespacefiles
Modules:
Are data/logic packages
Are created by writing Python or C extensions
Are used by imported
Classes:
Implement new objects
Are created by class statements
Are used by being called
Always live within a module

Oct 5, 2008

Learning python 读书笔记 PART 4

PART FOUR. FUNCTIONS
Chapter 12. Function Basics
calls:  myfunc(argv)
def, return, yield: def adder(a, b=1, *c): return a+b+c[0]
global:  def function(): global x; x = 'new'
lambda:  funcs = [lambda x: x**2, lambda x: x*3]
1. Coding Functions
def is a executable statement which create an object and assigns it to a name
arguments are passed by assignment
global declares module-level variables that are to be assigned
def <name> (arg1, arg2...):
    ...
    return <value>
def can executes at runtime
if test:
    def function():
else:
    def function():
2. Definitions and Calls
Polymorphism in Python: because python is a dynamically typed language, every operation is polymorphic in python
in python, code is not supposed to care about specific data types.

Chapter 13. Scopes and Arguments
1. Scope Rules
Name <--> Namespace
The enclosing module is a global scope
The global scope spans a single file only
Each call to a function is a new local scope
Assigned names are local, unless declared global
All other names are enclosing locals, globals, or built-ins
LEGB: local --> enclosing functions --> global --> built-in
the built-in scope
>>> import __builtin__
>>> dir(__builtin__)
zip <--> import __builtin__,  __builtin__.zip
2. The global Statements
3. Scope and Nested Functions
LEGB: statically nested scope
lambda: an expression that generates a new function to be called later, much like def statement
4. Passing Arguments
immutable arguments <--> C's "by value" mode
mutable arguments <--> C's "by pointer" mode
Avoiding mutable arguments change:
pass a copy or tuple
Simulating output parameters:
>>> def multiple(x,y):
    x = 2
    y = [3,4]  #change local names only
    return x,y #return new values in a tuple(not two values)
>>> x = 1
>>> y = [1,2]
>>> x,y = multiple(x,y)  #assign result to caller's names
>>> x,y
(2, [3, 4])
5. Special Argument Matching Modes
func(value)    : Normal argument: matched by position
func(name=value)    : Keyword argument: matched by name
self documention, more meaningful
def func(name)   
def func(name=value)    : default argument value, if not passed in the call
make some arguments optional
def func(*name)    : Matchs remaining positional args(in a tuple)
>>>def f(*args): print args
def func(**name)    : Matchs remaining keyword args(in a dict)
>>>def f(**args): print args
>>>f(a=1,b=2)
{'a':1, 'b':2}
Argument Matching
rules:
key arguments after non-keyargument
*name after normal argument
**name last
Matching steps:
non-key argus --> key word argus --> extra non-key argus --> extra key argus -->default values

Chapter 14. Advanced Function Topics
1. Anonymous Functions: lambda
lambda expression creates a function to be called later, but returns it instead of assigning it to a name
lambda argu1, argu2, argu3...arguN: expression using argus
lambda bodies are single expression, not a block of statements
example1:
L = [(lambda x: x**1),(lambda x: x**2), (lambda x: x**3)]
for f in L
    print f(2)
print L[0](2)
example2:
key = 'b'
{'a': (lambda f1),
  'b': (lambda f2),
}[b]()
is equivalent to
def f1():...
def f2():...
...
key = ...
{'a':f1, 'b':f2}[key]()
How(not) to obfuscate your python code
((a and b) or c) is roughly equivalent to:
if a: b else: c
(C's a?b:c)
2. Applying Functions to Arguments
The apply built-in
apply(func, argus) == func(argus)
argument list is passed by tuple
if <test>:
    action,args = func1, arguments_a
else
    action,args = func2, arguments_b
...
apply(action,args)
3. Functions Over Sequences
>>> counter = [1,2,3,4]
>>> def func(x): return x + 10
>>> map(func,counter)
[11, 12, 13, 14]
>>>map((lambda x: x + 3), counter)
[3,4,5,6]
map(func,[1,2,3],[4,5,6]) #[func(1,4),func(2,5),func(3,6)]
4. Functional Programing Tools
filter
>>>filter((lambda x: x>0), range(-5,5))
[1,2,3,4]
reduce
>>>reduce((lambda x, y: x+y), [1,2,3,4]) 
10
>>>import operator
>>>reduce(opetator.add, [1,2,3,4])
5. List Comperhensions
[x ** 2 for x in range(10)]
map((lambda x: x ** 2), range(10))
[x for x in range(5) if x%2 == 0]
filter((lambda x: x%2 == 0), range(5))
map((lambda x: x**2), filter((lambda x: x%2 == 0),range(10)))
the genaral structure of list comprehensions
[expression for target1 in sequence 1 [if condition]
                for target2 in sequence 2 [if condition]....
                for targetN in sequence N [if condition]]
list comperhension and map are faster than for loop.
6. Generators and Iterators
Generators yield a value rather than returning one. The yield statment suspends the function and sends a value back to the caller and allow the function to resume from where it left off.
>>> def gensqure(N):
    for i in range(N):
        yield i ** 2
>>>x=gensqure(10)
>>>x.next(), x.next()...
Iterators and built-in type: iter(L)
__iter__ method

Learning python 读书笔记 PART 3

PART THREE: Statements and Syntax
Chapter 8. Assignment, Expressions, and Print
program  are composed of  modules contains statements contain expressions create and process objects
1. Assignment Statements
a = 'a'
a, b = 'a', 'b'   #tuple assignment
[a,b] = ['a','b']    #List assignment
a = b = 'c'    #Mutiple-assignment
L = L + [3], L = L + [5,6]    #Concatenate(create a new object)
L.append(3), L.extend([4,5])    #Faster, but in-place(add at the and of memory)
L += [9,10]    #Mapped to L.extend([9,10]): the faster mothed
2. Expression Statements
3. Print Statements
print a,b,    #don't add newline at the end of text
print >>myfile a,b    #send data to myfile.write, not to sys.stdout.write
redirecting the Output Stream
import sys
sys.stdout = open('myfile', 'a')
print and stdout
class FileFaker:
    def write(self, string)  #do something with the string
import sys
    sys.stdout = FileFaker()

Chapter 9. if Tests
1. if stataments
if: elif: else:
if 1:
    print 'true'
else:
    print 'false'
switch & case:
*if choice = 'a':
    print 'aaa'
elif choice = 'b':
    print 'bbb'
else:
    print 'default'
choice = 'b'
*print {'a':'aaa','b':'bbb'}[choice]
*branch = {'a':'aaa','b':'bbb'}
  print branch.get('a', 'bad choice')
2. truth tests
2<3, 3<2   #Less-than: return 1 or 0
short circuit evaluation
2 or 3, 3 or 2   #(2,3) Return left operand if true. Else return right operand.
[] or 3   #3
[] or {}   #{}
2 and 3, 3 and 2   #(3,2) return left operand if false. Else return right operand.

Chapter 10. while and for Loops
1. while loops
while <test>:
     <statement1>
     if <test2>: break    #Exit loop now, skip now
     if <test2>: continue    #goto top of loop now   
else:
     <statement2>    #if we didn't hit break
breaks, continue, pass and the loop else
Emulating C while Loops

C assignments return the value assignment; Python assignments are just statements, not expressions
C: while ((x = next()) != NULL){process x...}
Python equivalent:
*while 1:
    x = next()
    if not x: break
    ...process...
x = 1
*while x:
    x = next()
    if x:
    ...process
2. for loops
for <target> in <object>:
    <statements>
else:
    <statements>  #if we didn't hit break
3. loop variations
range

Counter Loops
range(3)  #[0,1,2]
range(2,5) #[2,3,4]
range(0,10,2)  #[0,2,4,6,8]
*for item in X: print item
*i = 0
 while i < len(X)
     print x[i],; i += 1
*for i in range(len(x)): print X[i]
Nonexhaustive Traversals
S = 'abcdefghijk'
for i in range(0, len(s), 2) print S[i],  #manual for indexing
for i in S[::2]: print x
Changing Lists
for i in range(len(L)):
    L[i] += 1
zip and map
zip can enable us to visit multiple sequences in parallel
L1 = [1,2,3], L2 = [4,5,6]
zip(L1,L2)   #[(1,4),(2,5),[3,6]]
for (x,y) in zip(L1,L2):
    print x, y,
when argument lengths differ, zip choose the shortest length
map(None, L1, L2)
map choose the longest length and filled empty items with "None"
Dictionary Construction with zip
>>> keys = ['a','b','c']
>>> values = [1,2,3]
>>> zip(keys,values)
[('a', 1), ('b', 2), ('c', 3)]
>>> D = {}
>>> for(k,v)in zip(keys,values):
    D[k]= v   
>>> D
{'a': 1, 'c': 3, 'b': 2}
>>> D2 = dict(zip(keys,values))
>>> D2
{'a': 1, 'c': 3, 'b': 2}
File Scanners
file = open('test.txt', 'r')
while 1:
    line = file.readline()
    if not line: break
    print line
1. for line in open('test.txt').readlines(): print line
2. for line in open('test.txt').xreadlines(): print line
3. for line in open('test.txt'): print line
xreadlines loads lines on demand, "3" relies on iterators, is equivalent of xreadlines

Chapter 11. Documenting Python Code
1. the python document interlude

dir(): Lists of attributes  available on objects
__doc__: In-file documentation attached to objects
docstrings
User-defined docstrings: strings at the top of file, method and class
built-in docstring:
import sys
print sys.__doc__
print int.__doc__, print open.__doc__
pydoc
help(sys)
2. common coding gotthas
Don't forget the colons
Start in column 1
Blank lines matter at the interactive prompt:
mean the end of compound statement
Indent consistently
Don't coding C in Python:
don't embed assignment statements in while loop tests
Use simple for loop instead of while or range:
for loop is simple and fast
Don't expect results from functions that change objects in-place:
append(), sort(), append(), extend()
myList = myList.append(X)  #set myList to None
Always use parenthesis to call a function
Don't use extensions or paths in imports and reloads

Oct 4, 2008

Learning python 读书笔记(6, 7章)

Chapter 6: Lists and Dictionaries
1. List
Methods: grow, sort, search, reverse, append, extend, append
del L[x:y], L[x:y]=[a,b,c]
range(x), xrange(x,y), L.pop()
2. List in Action
Slice assignment: delete + insert
L.append(x) < -- > L+[x]
3. Dictionaries
D.keys(), D.values(), D.items():
create a new list
D.copy(), D.get(k, default),
D2.update(D1): merges the keys and values of one directory into another, blindly overwriting values of the same key.
D.has_key(k), k in D
D = dict(zip(keyslist, valueslist))
4. Dictionaries in Action
sequence operation don’t work.
Assigning to new indexes adds entries.
keys need not always be strings.(can be other immutable object)
Using dictionaries to simulate flexible lists Using dictionaries for sparse data structures
Matrix = {}
Matrix[(2,3,4)] = 88: the number at position (2,3,4) is 88
Using dictionaries as “reconds”
Dictionary interfaces
import anydbm
file = anydbm.open(“filename”)
file [‘key’] = ‘data’ #store data by key
data = file[‘key’] #fetch data by key

Chapter 7: Tuples, Files, and Everything Else
1. Tuples

simple groups of objects, cannot change in place(immutable), don't support any method calls
>>> (1,2) + (3,4)
(1, 2, 3, 4)
>>> (1,2) * 3
(1, 2, 1, 2, 1, 2)
>>> T = ('1', '2', '3')
>>> tmp = list(T)
>>> tmp
['1', '2', '3']
>>> T2 = tuple(tmp)
>>> T2
('1', '2', '3')
>>> T = (1, [2,3], 4)
>>> T[1][0] = 5 #works
>>> T[0] = 0 #Fails
2. Files
input = open('path', 'r'), output = open ('path', 'w')  #mode: r, w, a
S = input.read(), S = input.read(N) # N bytes
S = input.readline(), S = input.readlines()
output.write(S), output.writelines(L), output.close()
seek: reset current position in file, flush: buffered output write into disk
3. Type Categories Revisited
Operator Overloading:

class MySquence:
    def __getitem__(self, index):
        #called on self[index]
    del __add__(self, other):
        #called on self + other
4. Object Generality
Lists, dictionaries, and tuples can: 1. hold any kind of object 2. arbitrarily nested
Lists and dictionaries can dynamically grow and shrink.
5. References Versus Copies
No reference to the same object:

A = L[:]    #instead of: A = L (or list(L))
B = D.copy()    #instead of: B = D
empty-limit slices and copy method only do a top-level copy!
nested copy:
import copy
X = copy.deepcopy(Y)
6. Comparisons, Equality, and Truth
L1 == L2, L1 is L2    #Equivalent? Same object?
But short string: S1 = 'spam', S2 = 'spam' # S1==S2: true, S1 is S2: true
Numbers are true if nonzero
Other objects are true if nonempty
None: much like NULL in C
L = [None] * 100
bool: True, False

Oct 2, 2008

Learning python 读书笔记(1--5章)

PART ONE: Getting Started
Chapter 1: A Python Q&A Session
Chapter 2: How python runs programs
1. Source(x.py) --> Byte Code(x.pyc) --> runtime(PVM)
2. CPython, Jython and Python.net
Psyco: Just-in-Time Compiler
3. Frozen Binaries: program + PVM = binary executable program.
Py2exe(for windows), Installer(Linux & Unix), freeze(original)
Chapter3: How you run programs
1. Unix executable scripts: start with #!/usr/local/bin/python
2. raw_input trick: pause the script
3. import and reload
imports are too expensive an operation to repeat, so when we use reload() instead.
4. Attributes: import xx & from xx import yy. yy are the attributes in the python file xx.
5. IDE: IDLE, Komodo, PythonWorks, PythonWin, Visual Python(plugin for VS).
6. text editor: see http://www.python.org/editors

PATR TWO: Types and Operations
Chapter4: Numbers
1. programs  modules  statements  expressions.
2. Numbers: Normal integers(C longs); Long integers(unlimited size); Floating-point(C doubles);Octal and hex literals; Complex number literals.
3. NumPy(Numeric Python).
4. When use a variable that has never been assigned, Pythons report an error rather than a default value.
5. Numeric representation:
>>>b/a #Auto echo output: more digits
>>>print b/a #print rounds off digits.
>>>repr(num) #Used by echos: as cod form
>>>str(num) #Used by print: user-friendly form
6. Division: Classic, Floor and True
x/y: Classic division
x//y: Floor devision
>>>from __future__import division
7. >>>import math
>>>math.pi, math.e
8. >>>int(‘0100’), int(‘0100’, 8), int(‘0x40’, 16) #100, 64, 64
>>>oct(64), hex(64) #’0100’, ‘0x40’
>>>eval(‘100’), eval(‘0100’), eval(‘0x40’) #100, 64, 64
9. >>>a=3 # a: Names (reference) 3: Object
10. >>>L1 = [2, 3, 4]
>>>L2 = L1
>>>L1 = 24 #L2 is not changed
>>>L1[0] = 24 #L2 = [24, 3, 4]
Chapter 5: Strings
1. >>> s = ‘a\nb\tc’
>>> s # output is the original sequence
>>> print s #output is translated sequence
>>>len(s) #5
2. If python doesn’t recognize the character after ‘\’, it simple keeps the backslash in the resulting string.
3. Raw stirng: r’xxxx’
4. u‘xxx’: Unicode string
5. >>> abc = 'abc'
>>> for i in abc:
print i
a
b
c
>>> for i in abc:
print i,
a b c
6. Index and slicing:
>>> num = '123456'
>>> num[1:3], num[5:], num[:-4]
('23', '6', '12')
>>> num[::2], num[::-1], num[0:-3:2]
('135', '654321', '13')
7. String conversion tools:
>>>int(“42”), str(42) #Convert from/to string
>>>string.atoi(“42”), ‘42’ #older techniques
8. You cannot change a string in place(by assigning an index).
9. String formatting
>>> "%s %d %s" %('I', 4, 'you')
'I 4 you'
%s: string
%r: s, but uses repr()
%c: character
%d: decimal (integer)
%i: integer
%u: unsigned integer
%o, %x, %X: Octal, Hex, Hex uppercase
%e, %E: floating-point exponent
%f: float point
%g, %G: floating-point e or f
%%: %
%[(names)][flag][width][.precision]code
>>> x = 1234
>>> res = "integers:...%d...%+d...%-6d...%06d" %(x, x, x, x)
>>> res
'integers:...1234...+1234...1234 ...001234'
10. String methods:
X.method(arguments) == string.method(X, arguments)
list(); join(); capitalize(); center(width)…

Jan 21, 2008

The C Puzzle Book (C语言解惑)读书笔记

每年在火车回家坐火车都是一种折磨,不过这次运气不错,一来认识了两个聊得来的朋友,二来带了一本《The C Puzzle Book》,翻翻看看,隔了一年多没碰C,有些问题是实实在在地不会,有些问题是自己粗心得挺搞笑。

Chapter 1 操作符
a. z+=-x ++ + ++y ==> z+=-(x++) + (++y)
but, x+++++y ==> x++ ++ +y 无意义
b.~01 == 1…10 != 10 ^_^
c. ~x|x == 111.. 1 恒等于 -1
d.y = -8; y >>= 3 y并不一定为-1,有些计算机右移时不保留操作数的符号位
e. z += x z+= (xf. z>=y>=z ^_^
简简单单的符号优先级问题本来以为背熟了表就差不多,可还是错了上面几个,蛮郁闷。

Chapter2 基本类型
a. define PRINT(format,x) Printf(#x " = %" #format "\n", x)
PRINT (d,"5") ?
显然打印的是指针地址,不过刚看时笨得没发现
int x= -2, unsigned int ux = -2 PRINT(o,x) PRINT(o,ux) ?
无论带符号还是无符号,-2都是那串01
b. 3.(注意后面那个.) …………
c. c语言中,即使运算发生了溢出,结果仍将是合法的数值。
主要是向上向下转型的问题,结合运算符优先级,挺容易搞混的。细节,细节!

Chapter3 头文件
#define PR (fmt, val) printf(#val " = %" #fmt "\t", (val))
#define NL putchat('\n')
#define PRINT1 (f,x1) PR(f,x1), NL
#define PEINR2 (f,x1,x2) PR(f,x1), PRINT1(f,x2), NL
... ...
一层一层往下套吧。。

Chapter4 控制流
a.if也能短路的哦
b.if( x=y ); x=3 看见那个分号了没?呵呵
c.while( y<10 ){x=y++; z=++y;} y++了两次哦,大意大意。

Chapter5 编程风格