CS 41: Python编程完整课程提纲
课程概览
课程名称 :CS 41 - Python编程
时间跨度 :2023年4月-5月
授课团队:Arpit, Chase, Will, Parth, Tara
第一部分:Python基础与数据结构
课程1:数据结构与面向对象编程(4月11日)
一、课程信息
- Assignment 0截止,组队最后期限
- Assignment 1(小组作业)发布
- Section分组:Arpit-Econ 206, Chase-380-381T, Will-Encina West 208
二、内置数据结构对比
| 数据结构 | 可变性 | 有序性 | 查找复杂度 | 定界符 | 典型应用 |
|---|---|---|---|---|---|
| List | ✔ | ✔ | O(n) | [] |
顺序数据、需要修改 |
| Tuple | ✘ | ✔ | O(n) | () |
不可变数据、字典键 |
| Set | ✔ | ✘ | O(1) | {} |
去重、成员检测 |
| Dictionary | ✔ | ✘ | O(1) | {} |
键值映射 |
Lists(列表):
- 可变、有序、异构
- 常用方法:
.append(),.remove(),.pop(),.sort()
Tuples(元组):
- 不可变、有序、可哈希
- 优势:存储效率高、可作为字典键
- 注意:存储不可变引用,但引用的对象可能可变
Sets(集合):
- 可变、无序、唯一
- 数学运算:
&(交),|(并),-(差),^(对称差) - 元素必须可哈希
Dictionaries(字典):
- 可变、关联性、键唯一
- 常用方法:
.get(),.keys(),.values(),.items()
三、集合操作模式
python
len(collection) # 长度
for elem in collection: ... # 遍历
list("abc"), set("abc") # 类型转换
enumerate(collection) # 枚举
sorted(collection) # 排序
zip(list1, list2) # 配对
range(start, stop, step) # 范围
四、列表推导式
python
# 列表推导
[fn(x) for x in iterable if cond(x)]
# 字典推导
{f(k): g(v) for k, v in iterable if cond(k, v)}
模式:遍历集合 → 检查条件 → 应用操作
课程2:类与面向对象(4月11日续)
一、实际问题:Stanford学生课程管理系统
- 学生实体:姓名、SUNet ID、课程、成绩
- 课程实体:ID、院系、课程号、学期、先修课、学生
- 功能:选课、先修课检查
二、类的概念
python
class House:
utilities = {'electricity': 'A&E #8675309'} # 类属性
def __init__(self): # 构造函数
self.locked = True # 实例属性
类比:
- 类 = 蓝图(Blueprint)
- 实例 = 实际房屋(Instance)
三、self参数
- 方法的第一个参数是对象自身引用
- 传统命名为
self instance.method(args)≈function(instance, args)
四、自定义实例化
python
class Student:
def __init__(self, name, sunet):
self.name = name.title()
if not set(sunet) <= set('0123456789'):
raise ValueError(f"Invalid SUNet: {sunet}")
self.sunet = sunet
五、魔术方法
python
str(x) → x.__str__()
x == y → x.__eq__(y)
x < y → x.__lt__(y)
x + y → x.__add__(y)
len(x) → x.__len__()
hash(x) → x.__hash__()
el in x → x.__contains__(el)
课程3:电子学入门(4月18日)
一、为什么学电子学?
- 目标:构建实体物品(We can build physical stuff!!)
- 作业:Assignment 2 - augment.py
二、电子学基础三要素
1. 电流(Current)
- 电子的流动,单位:安培(A)
- 类比:水流过管道
2. 电压(Voltage)
- 电势差,单位:伏特(V)
- 作用:推动电流流动
- 类比:水压
3. 电阻(Resistance)
- 阻碍电流的特性
- 类比:管道中的路障
欧姆定律:V = I × R
接地(Ground):零电压参考点,电流回路
三、Micro:bit V2
主要功能:
- 5×5 LED矩阵显示
- 2个可编程按钮
- 加速度计、指南针、温度传感器
- GPIO引脚(General Purpose Input/Output)
GPIO应用:
- 输入/输出操作
- 连接外部传感器和执行器
- 与传统电路接口
四、人体导电实验
- ⚠️ 警告:仅在超低电流和电压下安全
- 原理:水含有离子可导电,人体约60%是水
- 主题:Human Connection!!
第二部分:网络与数据交互
课程4:Python与网络(4月25日)
一、课程进度
| 周次 | 主题 | 核心问题 |
|---|---|---|
| Week 1 | Python基础 | 如何操作?Python哲学? |
| Week 2 | 数据结构与OOP | 如何扩展功能? |
| Week 3 | 电子学 | 如何增强物理设备? |
| Week 4 | Python与网络 | 如何与互联网交互? |
二、互联网工作原理
IP地址结构:
128.12.123.184
├─────┬─────┤├──┬──┤
网络标识符 主机标识符
DNS解析:
google.com → 172.217.5.110
路由追踪:
bash
$ traceroute google.com
1 Stanford网络
2-5 SUNet路由器
6-7 CENIC网络(加州研究与教育网络)
...
15 Google服务器
三、HTTP请求
请求组成:
http
GET / HTTP/2
Host: www.google.com
User-Agent: Mozilla/5.0...
Accept: text/html...
Accept-Language: en-US,en;q=0.5
Python requests库:
python
import requests
# 基本GET
r = requests.get(url)
# 带请求头
r = requests.get(url, headers={'Accept-Language': 'es'})
# 带参数
r = requests.get('https://google.com/search', params={'q': 'unicorns'})
# POST请求
r = requests.post(url, data={'key': 'value'})
四、响应数据处理
数据格式:
- HTML:网页内容
- JSON:对象字符串,最常用
- Text:纯文本
- Other:图像、PDF等
处理响应:
python
r.content # bytes - 原始字节数据
r.text # str - 字符串
r.json() # dict - Python字典 ✓ 最常用
JSON示例:
json
{
"id": 317,
"type": "general",
"setup": "Why are oranges the smartest fruit?",
"punchline": "Because they are made to concentrate."
}
五、API(应用程序编程接口)
定义:
- 应用程序间通信的方式
- 程序员友好(非用户友好)
- 其他程序可以接入
示例:https://official-joke-api.appspot.com/
第三部分:高级Python特性
课程5:底层Python(5月9日)
一、通知事项
- Assignment 2: augment.py一周后截止
- 下周带增强设备展示
- 过渡到期末项目
- 期末项目披萨派对 🥹
二、多线程(Multithreading)
问题场景:下载多个文件
单线程执行时间:
url1: 0s开始 → 10.5s完成
url2: 10.5s开始 → 21s完成
url3: 21s开始 → 31.5s完成
url4: 31.5s开始 → 42s完成
总计:约42秒
多线程执行时间:
url1-4: 0-2s并行发送请求
等待响应:2-11.5s
总计:约11.5秒(节省30秒!)
关键思想:CPU等待时可切换到其他任务
操作系统线程管理:
- 进程(Process)= 程序
- 线程(Thread)= 进程内的指令序列
- OS知道线程何时等待,可切换执行流
Python实现:
python
from threading import Thread
# 单线程
download_picture(url, filename)
# 多线程
t = Thread(target=download_picture, args=(url, filename))
t.start()
t.join()
# 多个线程
t1 = Thread(target=download_picture, args=(url1, file1))
t2 = Thread(target=download_picture, args=(url2, file2))
t1.start()
t2.start()
t1.join()
t2.join()
三、全局解释器锁(GIL)
引用计数机制:
python
import sys
lst = []
extra_ref = lst
sys.getrefcount(lst) # => 3
GIL存在原因:
- Python使用引用计数管理内存
- 多线程同时访问对象会混乱引用计数
- GIL确保同一时间只有一个线程执行Python代码
I/O密集型 vs CPU密集型:
| 类型 | 特点 | 多线程效果 | 示例 |
|---|---|---|---|
| I/O密集型 | CPU等待外部资源 | ✓ 有效 | 网络请求、文件读写 |
| CPU密集型 | CPU持续计算 | ✗ 无效 | 数学计算、数据处理 |
python
# I/O密集型(多线程有效)
requests.get(url) # 等待网络响应
# CPU密集型(多线程无效,因为GIL)
def sum_upto(n):
output = 0
for i in range(1, n+1):
output += i
return output
C++ vs Python:
- C++无GIL,可真正并行
- 多核CPU(如10核)可同时执行10条指令
- Python线程受GIL限制,无法利用多核
四、用C/C++扩展Python
CPython解释器:
- 用C编写的Python解释器
- 可以指示解释器直接运行C代码
python
# Python调用
import my_c_module
my_c_module.method('unicorns', 1)
c
// C实现
static PyObject* method(PyObject *self, PyObject *args) {
char *s;
int n;
if (!PyArg_ParseTuple(args, "si", &s, &n))
return NULL;
// 处理s和n
}
使用C扩展的原因:
- 性能提升
- 绕过GIL实现真正并行
- 访问底层功能
- 集成现有C库
课程6:函数与函数式编程(5月16日)
一、课程规划
| 课程 | 主题 | 深度 |
|---|---|---|
| Lecture 6 | 底层Python | 深入探讨 |
| Lecture 7 | 函数与函数式编程 | 深入探讨 |
| Lecture 8 | 标准库与第三方库 | 浅层探讨 |
| Lecture 9 | 游戏开发 | 浅层探讨 |
| Lecture 10 | 期末项目展示 | 准备展示 |
二、可变参数(Variadic Arguments)
*args - 位置参数:
python
def my_function(*args):
for i, arg in enumerate(args):
print(f'Argument {i}: {arg}')
my_function(2, 'many', 'arguments')
# Argument 0: 2
# Argument 1: many
# Argument 2: arguments
- 打包为元组(tuple)
**kwargs - 关键字参数:
python
def print_table(**kwargs):
for key, value in kwargs.items():
print(f"{key} | {value}")
print_table(name='Arpit', title='TA', course='CS 41')
- 打包为字典(dictionary)
组合使用:
python
def generic_fn(*args, **kwargs):
...
generic_fn(1, 2, buckle_my='shoe')
三、函数作为对象
验证:
python
def my_function(a, b, c):
...
type(my_function) # => function
hex(id(my_function)) # => '0x10680f880'
对象能做的事:
- 赋值给变量:
python
def add(a, b):
return a + b
combine = add
combine(1, 2) # => 3
- 作为参数传递:
python
sorted(['parth', 'tara', 'will'], key=len)
- 从函数返回:
python
def is_multiple_of(n):
def test(x):
return n % x == 0
return test
四、装饰器(Decorators)
基本结构:
python
def print_args(func):
def modified_func(*args, **kwargs):
print(f'Positional args: {args}')
print(f'Keyword args: {kwargs}')
return func(*args, **kwargs)
return modified_func
使用方式:
python
# 手动装饰
def add_mult(a, b, c):
return (a + b) * c
with_print = print_args(add_mult)
# 覆盖原函数
add_mult = print_args(add_mult)
# @语法糖
@print_args
def add_mult(a, b, c):
return (a + b) * c
装饰器工作流程:
- 接受函数作为参数
- 定义通用函数
- 做一些事情(如打印参数)
- 复制原函数行为
- 返回修改后的函数
Flask路由示例:
python
@app.route('/', methods=['GET'])
def greet():
return 'Hello world!'
五、生成器(Generators)
定义:可恢复的函数
基础实现:
python
def fibbi():
a = 0
b = 1
while True:
temp = a + b
a = b
b = temp
yield a
f = fibbi()
next(f) # => 1
next(f) # => 1
next(f) # => 2
特点:
- 使用
yield而不是return - 保存函数状态
- 可处理无限序列
查看状态:
python
next(f) # => 8
f.gi_frame.f_locals # => {'a': 8, 'b': 13}
遍历生成器:
python
for i, x in enumerate(f):
print(f'The {i+1}th Fibonacci number is: {x}')
减少内存使用:
python
# 列表:占用大量内存
sum([x**2 for x in range(100_000)])
# 生成器:节省内存
sum((x**2 for x in range(100_000)))
生成器推导式:
python
g = (x**2 for x in range(100) if x % 2 != 0)
next(g) # => 1
next(g) # => 9
next(g) # => 25
课程7:Lambda与标准库(5月23日)
一、Lambda匿名函数
语法:
python
lambda params : expression
# 示例
lambda x, y : x**2 + y**2
# 等价于
def square_add_two(x, y):
return x**2 + y**2
# 直接调用
(lambda x, y : x**2 + y**2)(8, 5) # => 89
Map函数:
python
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, numbers))
# => [1, 4, 9, 16, 25]
二、标准库概述
定义:
- 随Python一起提供的包和模块
- 只需import即可访问
- 官方文档:https://docs.python.org/3/library/
模块 vs 包:
- 模块(Module):可重用代码的最小单元(文件)
- 包(Package):模块的逻辑集合
导入方式:
python
import sound
sound.effects.echo.echofilter(a, b)
from sound.effects import echo
echo.echofilter(a, b)
from sound.effects.echo import echofilter
echofilter(a, b)
三、常用标准库
1. pickle - 对象序列化
python
import pickle
# 保存
with open('data.pkl', 'wb') as f:
pickle.dump(data, f)
# 加载
with open('data.pkl', 'rb') as f:
data = pickle.load(f)
- 用途:高效存储、进程间传递
- ⚠️ 安全警告:只加载可信来源的pickle文件
2. pdb - Python调试器
python
# 文件内调试
import pdb
pdb.set_trace()
# 终端调试
python3 -m pdb file.py
3. collections - 特殊容器
python
from collections import Counter, defaultdict, deque, namedtuple
# Counter - 计数器
Counter(['apple', 'banana', 'apple'])
# Counter({'apple': 2, 'banana': 1})
# defaultdict - 默认字典
dd = defaultdict(list)
dd['fruits'].append('apple')
# deque - 双端队列
dq = deque([1, 2, 3])
dq.appendleft(0)
# namedtuple - 命名元组
Point = namedtuple('Point', ['x', 'y'])
p = Point(11, 22)
4. functools - 函数工具
python
from functools import lru_cache, partial, reduce
# lru_cache - 缓存装饰器
@lru_cache(maxsize=128)
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2)
# partial - 部分函数
square = partial(power, exponent=2)
# reduce - 归约
product = reduce(lambda x, y: x * y, [1,2,3,4,5])
5. itertools - 迭代器工具
python
from itertools import count, cycle, chain, combinations, permutations
count(start=10, step=2) # 无限计数
cycle(['red', 'green', 'blue']) # 循环迭代
chain([1,2], [3,4]) # 链接
combinations('ABC', 2) # 组合
permutations('ABC', 2) # 排列
6. re - 正则表达式
python
import re
# 电话号码匹配
pattern = r"\(\d{3}\)[- ]\d{3}-\d{4}"
phone = "(123) 456-7890"
re.match(pattern, phone)
# 查找所有
numbers = re.findall(r'\d+', "Numbers: 42, 123, 7")
# 替换
new_text = re.sub(r'World', 'Python', "Hello World")
# 分割
fruits = re.split(r'[,;:]', "apple,banana;cherry")
四、第三方包
流行包:
- Flask:Web框架
- NumPy:数值计算
- Pandas:数据分析
- Requests:HTTP请求
安装:
bash
pip install package_name
⚠️ pip安全警告(2018年真实案例):
- 恶意包"acqusition"模仿"acquisition"
- 包含收集SSH和GPG密钥的代码
- 安全建议 :
- 仔细检查包名拼写
- 验证包来源
- 查看下载量和维护情况
- 阅读官方文档
第四部分:实践应用
课程8:游戏开发(5月24日)
一、Pygame基础
安装:
bash
pip install pygame
游戏循环三要素:
- 游戏循环(Game Loop)- 持续运行
- 事件处理(Event Handling)- 响应输入
- 绘制更新(Draw & Update)- 显示状态
二、事件系统
事件类型:
- QUIT:退出
- KEYDOWN/KEYUP:按键
- MOUSEMOTION:鼠标移动
- MOUSEBUTTONDOWN/UP:鼠标按钮
- JOYAXISMOTION等:游戏手柄
事件处理:
python
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
# 处理左键
三、第一个图形窗口
python
import pygame
pygame.init()
screen = pygame.display.set_mode((500, 500))
white = (255, 255, 255)
blue = (0, 0, 255)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
screen.fill(white)
pygame.draw.circle(screen, blue, (250, 250), 75)
pygame.display.update()
pygame.quit()
代码详解:
pygame.init()- 初始化set_mode((w, h))- 创建窗口(R, G, B)- 颜色元组screen.fill(color)- 填充背景pygame.draw.circle(screen, color, (x,y), r)- 绘制圆pygame.display.update()- 刷新显示
四、贪吃蛇游戏
核心组件:
- 常量定义:
python
white = (255, 255, 255)
blue = (50, 153, 213)
green = (0, 255, 0)
dis_width = 600
dis_height = 400
block_size = 10
snake_length = 15
- 数据结构:
python
# 蛇:坐标元组列表
snake = [(100, 100), (100, 110), (100, 120)]
# 蛇头:snake[-1]
# 蛇尾:snake[0]
- 键盘控制:
python
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change = -block_size
y_change = 0
# 其他方向类似
- 移动算法:
python
# 添加新头
snake.append((new_x, new_y))
# 删除旧尾(如果没吃食物)
if not ate_food:
del snake[0]
- 食物生成:
python
def generate_food(snake):
while True:
food_x = random.randrange(0, dis_width, block_size)
food_y = random.randrange(0, dis_height, block_size)
if (food_x, food_y) not in snake:
return food_x, food_y
- 碰撞检测:
python
def check_collision(snake_head, food_x, food_y):
return snake_head[0] == food_x and snake_head[1] == food_y
- 帧率控制:
python
pygame.time.Clock().tick(15) # 15 FPS
游戏逻辑流程:
每帧:
1. 清空屏幕
2. 绘制蛇和食物
3. 处理事件
4. 更新位置
5. 检查碰撞
6. 如果吃到食物→增长+生成新食物
7. 控制帧率
8. 刷新显示
五、小组活动
任务:添加食物功能
- 蛇碰到食物时增长
- 食物随机出现
- 被吃后重新生成
- 提示:坐标必须是block_size的倍数
第五部分:期末项目
项目时间表
| 时间点 | 任务 |
|---|---|
| Week 5结束前 | 提交项目提案 |
| Week 7/8 | 与Parth/Tara会面讨论 |
| Week 10(5月31日) | 项目展示 |
| 期末 | 披萨派对 🥹 |
核心概念总结
一、Python数据结构决策树
需要存储什么?
├─ 单一值序列
│ ├─ 需要修改?
│ │ ├─ 是 → List
│ │ └─ 否 → Tuple
│ └─ 需要去重?
│ └─ 是 → Set
└─ 键值对映射 → Dictionary
二、多线程决策树
需要并发?
├─ 否 → 单线程
└─ 是 → 任务类型?
├─ I/O密集型(网络、文件)→ Python多线程 ✓
└─ CPU密集型(计算)
├─ C/C++扩展 ✓
└─ multiprocessing模块
三、函数式编程三支柱
1. 函数是一等公民
├─ 可赋值给变量
├─ 可作为参数
└─ 可作为返回值
2. 高阶函数
├─ 接受函数作为参数
├─ 返回函数
└─ 装饰器
3. 惰性求值
├─ 生成器
├─ 节省内存
└─ 处理无限序列
四、常用标准库速查
数据结构 :collections (Counter, defaultdict, deque)
函数工具 :functools (lru_cache, partial, reduce)
迭代工具 :itertools (count, cycle, chain, combinations)
文本处理 :re (正则表达式)
调试 :pdb
序列化:pickle
五、Pygame核心模式
python
# 标准游戏循环
pygame.init()
screen = pygame.display.set_mode((width, height))
clock = pygame.time.Clock