CS61A学习笔记

CS61A学习笔记 week1

是一门python课...用来速成一下python

记得很乱

~~ 绝赞更新中!~~ 开学了,下期休刊!

operators

\\ 整除
** exp

assignment statement

形如

a = b
a1,a2 = b1,b2

的语句,和c++不同的是无需声明变量类型。

其中第二个赋值语句,b1和b2不受当前语句的影响而改变,即先计算再赋值。

python的函数是可以通过赋值重定义的,如:

max = min

User-Defined Functions

形如

def <name>(<formal parameters>):
    return <return expression>

如:

def square(x): 
    return mul(x , x)
def sum_squares(x, y):
    return square(x) + square(y)

跟haskell一样应该是Indent-sensitive的

函数参数可以有默认值,也可以传参的时候改变默认值

None

python中的无返回值(默认返回值),type是NoneType

如:print的返回值是None,和c++里有返回值不一样。

举个例子:

print(print(1), print(2))

output:
1
2
None None

再说说print,print里不同的元素用逗号隔开,返回None。

features

使用 python -i sourse.py 来调用sourse里的函数

使用 --trace 来调试

Conditional statements

使用if、elif和else

如:

if x < 0:
    return -x
elif x == 0:
    return x
else:
    return x

能被判定成False的如:0、None、''、False

此种语句中只要进入一个suite后面的就不会再执行了

Boolean

使用首字母大写的True和False

Boolean operators

使用 and、or、not

注意and和or都是从左到右计算,如and左边为False就返回该False值了

并且这里返回的True或者False不一定是Bool值,如 8 and 9 会返回9

and中,如果所有值都为True,返回最后一个值

or中,如果所有值都为False,也返回最后一个值

Iteration

和c++差不多使用while和for

while <expression>:
    <suite>
for <variable> in <interable>:
	<suite>

支持break和continue。

assert

assert <expression>,<message>

Higher-order function

这部分可以参考haskell的curry化,python的lambda表达式和高阶函数也很好用。

作业

hw01,hw02,lab00,lab01

project1(hog)

CS61A学习笔记 week2

Environments for Higher-Order Functions

简单来说frame有parent关系,找一个变量就是依次往上找

Self-Reference

一个有趣的例子:

def print_all(x):
    print(x)
    return print_all

print_all(1)(3)(5)

在project hog里也有类似的实现,注意和c++不同的是懒惰计算,call的时候才计算

Decorators

一种语法,用于通过高阶函数decorate一个function,即把一个函数作为高阶函数的参数变成修饰过的另一个函数

在前面加上@

def trace(fn):
    def traced(*args):
        print('Calling',fn,'on argument',*args)
        return fn(*args)
    return traced

@trace
def triple(x):
    return 3*x

Recursion and Tree Recursion

就是递归

作业

hw03,lab02,lab03

CS61A学习笔记 week3

lists

>>> odds = [41,53,47,49]
>>> odds[1]
43

len

>>> len(odds)
4

append

>>> s = [2,3]
>>> t = [5,6]
>>> s.append(t)
>>> s
[2, 3, [5, 6]]

extend

>>> s = [2,3]
>>> s.extend(t)
>>> s
[2, 3, 5, 6]

+

>>> s = [2,3]
>>> a = s + t
>>> a
[2, 3, 5, 6]

slice assignment

\(s[a:b] = t\)

把在 \([a,b)\) 区间里的元素替换为 \(t\)

实测 \(a>=b\) 时替换到 \(a\) 元素之前

\(a\ b\) 默认值为序列左右两端

>>> b = a[1:]
>>> b
[3, 5, 6]
>>> s = [2,3]
>>> t = [5,6]
>>> s[0:0] = t
>>> s
[5, 6, 2, 3]
>>> s[3:] = t
>>> s
[5, 6, 2, 5, 6]
>>> s[2:] = t
>>> s
[5, 6, 5, 6]

pop

>>> s = [2,3]
>>> s.pop()
3
>>> s
[2]
>>> s.pop()
2
>>> s
[]
>>> s.pop()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: pop from empty list

remove

>>> t = [5,6,5,6]
>>> t.remove(6)
>>> t
[5, 5, 6]

containers

一个operator: in

>>> 41 in odds
True

For Statements and Ranges

可以枚举list里的元素:

for <name> in <expression>:
  	<suite>

只要iterable就可以For

range:连续整数,左闭右开,左端参数默认是0,iterable

可以使用list()把iterable的type转换成一个list

list comprehension

和haskell一样,不同的是要指定范围(in),语法上使用for

如:

>>> odds = [1,3,5,7,9]
>>> [x+1 for x in odds]
[2,4,6,8,10]
>>> [x+1 for x in odds if 25 % x ==0]
[2,6]

注意它的type是generator

strings

一个函数:exec()用于把string当作命令执行

string也可以当作字符数组访问,下标从0开始

string的list比较特殊,in操作符可以判断substring

Dictionary

对key值和value值建立映射,内置一些函数:

内部实现应该是hashtable

numerals = {'I': 1, 'V': 5, 'X': 10}
>>> numerals.keys()
dict_keys(['I', 'V', 'X'])
>>> numerals.values()
dict_values([1, 5, 10])
>>> numerals.items()
dict_items([('I', 1), ('V', 5), ('X', 10)])
>>> items = [('I', 1), ('V', 5), ('X', 10)]
>>> dict(items)
{'I': 1, 'V': 5, 'X': 10}
>>> 'X' in numerals
True
>>> numerals.get('X')
10
>>> numerals.get('X-ray')
>>> numerals.get('X-ray',0) # 默认值
0
# dictionary comprehension
>>> squares = {x:x*x for x in range(10)}
>>> squares[7]
49
>>> {[1]:2}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

Raising Exceptions

使用 python -0 打开调试模式,忽略所有assert

也可以使用raise:

raise <expression>
raise TypeError('111!')
#还有NameError,KeyError,RuntimeError

Try Statements

try:
    <try suite>
except <exception class> as <name>:
    <except suite>
...

如果 try suite 发生 的错误的话,执行 except suite

套娃的try在内层处理成功了就不会进入外层except

Reduce

相当于haskell的foldl

用法:

from functools import reduce
reduce(<function>,<list>,<initial_element>)
reduce(mul,[1,2,3],1)

Processing Container Values

一些自带函数:sum,max(可选key函数),all(iterable里所有元素都为True返回True),any(同理)

>>> max(range(10),key = lambda x: 7-(x-4)*(x-2))
3
# 即keyfunc(x)最大的x

Trees

用python的强强list来储存树结构

即第0个元素是根结点元素,后面每个元素是一个子树(也是list)

作业还只准你用它封装的东西,就很蠢。

Object

有关String的一些函数和method:

ord(s) #ascii
s.upper()
s.lower()
s.swapcase()

Mutation Operations

list 和 dictionary 是 mutable type,可以mutation

包括给 function 传参一个list或者dictionary,在function里改变这个参数,在外面也会改变(相当于c++引用传参)

Tuples

元组,非mutable的sequence

Identity & Equality

a is b # identity,是否bound到相同的元素
a == b # Equality,值是否相同

作业

lab04,lab05,hw04

project2(cat)

CS61A学习笔记 week4

nonlocal

在local frame里用 nonlocal 声明parent frame里的变量,把这个变量bound到nonlocal frame里

nonlocal <name>

python 是把声明变量和变量赋值都放在 assignment 写法里的,注意二者的区别

另外就是mutable的类型(list、dictionary): 不需要nonlocal也可以直接在local frame用parent frame的变量

Iterator

iter(iterable) : return an iterator
next(iterator) : return the next element in an iterator

dictionary有不同的iterators:

k = iter(d.keys())
v = iter(d.values())
i = iter(d.items())

如果dictionary改变了那么之前的iterator会失效。

For Statements

for一个iterator的时候,会枚举当前元素以及之后的所有元素

Built-in Iterator Functions

map,filter,zip: 和haskell的定义相同

但是注意这些函数得到的是一个iterator,并且计算是lazy的,只有把iterator遍历一遍才会计算。

reversed,list,tuple,sorted: 顾名思义,把iterator变成各种形式

next(incr, v) 当StopIteration时返回v

generator

属于iterator的一种

使用关键字 yeild

一个generator function可以返回多个值,用yeild标出,最后返回一个iterator包含所有返回值。

注意generator function的计算也是lazy的。

一种方便的写法:要得到一堆结果的时候可以全部yeild出来再用list转换

利用这个方法python也是可以得到无穷序列的

yeild from statement

for x in a:
    yield x

等价于

yeild from a

作业

lab06,lab07,hw05

midterm

CS61A学习笔记 week5

Class Statements

class <name>:
    <suite>

其中suite用def定义method

>>> class Account:
        def __init__(self, account_holder):
            self.balance = 0
            self.holder = account_holder

其中__init__是类似关键字的初始化函数,包含一个self和一些可选参数。

另一个关键字是__repr__,直接引用一个实例时的返回值。

Method

在class里定义其他函数:

def deposit(self, amount):
    self.balance += amount
    return self.balance

Attributes

built-in functions:

>>> getattr(john, 'balance') # = john.balance
>>> hasattr(john, 'balance') # check attrribute
True

Class里的Attributes可以是function,也可以是简单的值。

Methods and Functions

Object + Function = Bound method, 即把Object传入一个Class里的Function的self参数就得到了method

>>> Account.deposit(tom_account,1001) # <class 'function'>
1011
>>> tom_account.deposit(1000) # <class 'method'>
2011

Class Attributes

也可以开class里的全局变量:

class Account:
    interest = 0.02
    def __init__(self, account_holder):
        self.balance = 0
        self.holder = account_holder
   	...
...
>>> tom_account.interest
0.02
>>> jim_account.interest
0.02

instance attribute:self.name(在init里声明或者在外面assign)

class的这种变量也可以被self拿来用(self.interest)

Attribute Assignment

注意是Class attribute 还是 instance attribute

比较重要的是dot表达式的求值顺序:<expresion>.<name>

  1. 计算左侧表达式,得到object
  2. 如果左侧实例(instance)有一个这样的attribute,返回值
  3. 否则在对应的class里去找,返回值
  4. 如果找到的是一个函数,则返回bound method

那么如果当前实例和class里有重名attribute则优先返回实例里的。

对instance attribute的assignment不对class有影响。

Inheritance

从一个class继承到另一个class:

class <name>(<base class>):
    <suite>

找name也是一级一级往上找的

注意self是哪个instance的

super(): 另一种访问上一级class (base class) 的方式

Multiple Inheritance

attribute名称冲突时优先选在继承树上近的那个

John老师认为不好用(救世啊!)

Linked Lists

链表,作为class的例子

isinstance:判断是否为class的实例

@property:把method转化为attribute,不加括号可以直接调用

@<attribute>.setter: 用于已经@property的method,可以进行赋值等操作

Tree class

另一个例子

Memoization

python的一种记忆化写法:使用dictionary和decorator:

def memo(f):
    cache = {}
    def memoized(n):
        if n not in cache:
            cache[n] = f(n)
        return cache[n]
   	return memoized

Exponentiation

快速幂

String Representations

class里的关键字__str____repr__

__repr__ 返回一个python表达式(string),其运行的结果是object本身(eval(repr(object)) == object)

__str__ 返回一个更容易被人类理解的表达式,print出来的就是__str__

Implementing repr and str

instance attribute called __repr__ or __str__ is ignored!

Only class attributes are found

def repr(x):
    return type(x).__repr__(x)

注意,即使你在init里定义 self.__repr__ 也会被忽略

如果一个class没有定义str,会用repr作为代替

Special Method Names

再总结一波关键字!

__add__ : 调用+,左结合

__radd__ : +右结合

__bool__ __float__ : 强制转换

Example: Reading Files

使用open来打开文件

Sets

python的内置set

>>> s = {'one','two','three','four','four'}
>>> 'three' in s
True
>>> len(s)
4
>>> s.union({'one','five'}) # 并
{'three','five','one','four','two'}
>>> s.intersection({'six','five','four','three'})# 交
{'three','four'}
>>> s
{'three','one','four','two'} #union和intersection不改变s
>>> s.add(<object>)
>>> s.update(<tuple,list,dict>)
>>> s.discard(<object>)
>>> s.clear()

*args and **kwargs

*args: 剩下的无名参数(args是一个tuple)

*kwargs: 剩下的关键字参数(kwargs是一个dictionary)

如:

>>> def pr(*args,**kwargs):
        print('args=',args)
        print('kwargs=',kwargs)
>>> pr(1,2,3,a=2,b=4,c=6)
args= (1,2,3)
kwargs= {'a':2,'b':4,'c':6}

注意args和kwargs不是关键字,起作用的是前面几个星号,名称可以改变

星号

单星号:可以把list/tuple/dict的元素“取出来”,形成多个值,其中dict取键值

双星号:取dict中的value

还有就是上面args的用法

作业

lab08,lab09,hw06

project3(Ants)(big big project!)

CS61A学习笔记 week6

scheme

新语言!好像是project4要用python写一个interpreter!

> (Integer? 1)
#t
> (+ 1 2)
3

Special Forms

  • If expression: (if <predicate> <consequent> <alternative>)
  • And and or: (and <e1>...<en>),or(<e1>...<en>)
  • Binding symbols: define <symbol> <expression>
  • New procedures: define (<symbol> <formal parameters>) <body>

Lambda Expressions

(lambda (<formal-parameters>) <body>)

Lists

链表

cons: constructor

car: 返回第一个元素

cdr: 返回剩下的元素

nil: empty list

> (cons 1 (cons 2 nil))
(1 2)

Symbolic Programming

可以quote一个元素,不需要bound到value也可以使用变量:

> 'a
a
> (quote a)
a
> (list 1 'a)
(1 a)
> (list 1 a)
Error

Interpreters

表达式树那一套... 直接做project得了

Tail recursion

好像就是要在函数/if语句的末尾进行递归,不需要在递归完成后进行其他操作,这样编译器会优化栈空间

Programs as Data

大概意思是scheme所有的代码都是list

Macros

begin: eval一系列代码(死去的monad记忆突然开始攻击我)

macro:自定义special form,使用define-macro定义的函数不会先eval,相当于把参数先quote起来

主要方法是使用单引号在文本的层次上“模拟”出程序语句

作业

lab10(刚好10个question)

lab11

hw07

project4(scheme)

posted @ 2023-01-03 02:33  lcyfrog  阅读(564)  评论(0编辑  收藏  举报