Skip to content

Commit 161af9c

Browse files
committed
更新了部分代码
1 parent bdaac35 commit 161af9c

28 files changed

+2248
-71
lines changed

Day16-20/Python语言进阶.md

+628-4
Large diffs are not rendered by default.

Day16-20/code/example01.py

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
"""
2+
实现查找功能的模块
3+
"""
4+
5+
6+
def seq_search(items, elem):
7+
"""顺序查找"""
8+
for index, item in enumerate(items):
9+
if item == elem:
10+
return index
11+
return -1
12+
13+
14+
def bin_search(items, elem):
15+
"""折半查找(二分查找)"""
16+
start, end = 0, len(items) - 1
17+
while start <= end:
18+
mid = (start + end) // 2
19+
if elem < items[mid]:
20+
end = mid - 1
21+
elif elem > items[mid]:
22+
start = mid + 1
23+
else:
24+
return mid
25+
return -1

Day16-20/code/example02.py

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
"""
2+
排序 - 冒泡排序(简单O(N**2)) / 归并排序(高级O(N*log2N))
3+
冒泡排序
4+
34, 99, 52, 11, 47, 68, 50, 84
5+
34, 52, 11, 47, 68, 50, 84, 99
6+
34, 11, 47, 52, 50, 68, 84
7+
11, 34, 47, 50, 52, 68
8+
9+
快速排序
10+
34, 99, 52, 11, 47, 68, 50, 84
11+
{34, 11, 47}, {50}, {99, 52, 68, 84}
12+
{11}, {34}, {47}, {50}, {52, 68, 84}, {99}
13+
{11}, {34}, {47}, {50}, {52}, {68, 84}, {99}
14+
{11}, {34}, {47}, {50}, {52}, {68}, {84}, {99}
15+
16+
归并排序 - 分治法(divide-and-conquer)
17+
34, 99, 52, 11, 47, 68, 50, 84
18+
{34, 99, 52, 11}, {47, 68, 50, 84}
19+
{34, 99}, {52, 11}, {47, 68}, {50, 84}
20+
{34}, {99}, {52}, {11}, {47}, {68}, {50}, {84}
21+
{34, 99}, {11, 52}, {47, 68}, {50, 84}
22+
{11, 34, 52, 99}, {47, 50, 68, 84}
23+
{11, 34, 47, 50, 52, 68, 84, 99}
24+
25+
在使用分治法的时候通常都会使用到递归调用这种编程手段
26+
一个函数直接或间接的调用了自身就称之为递归调用
27+
"""
28+
29+
30+
# 9 1 2 3 4 5 6 7 8
31+
# 2 3 4 5 6 7 8 9 1
32+
# *前面的参数称为位置参数, *后面的参数称为命名关键字参数
33+
# 所谓命名关键字参数就是调用函数时必须以"参数名=参数值"的形式传入参数
34+
def bubble_sort(origin_items, *, comp=lambda x, y: x > y):
35+
"""冒泡排序"""
36+
items = origin_items[:]
37+
length = len(items)
38+
for i in range(1, length):
39+
swapped = False
40+
for j in range(0, length - i):
41+
if comp(items[j], items[j + 1]):
42+
items[j], items[j + 1] = items[j + 1], items[j]
43+
swapped = True
44+
if swapped:
45+
swapped = False
46+
for j in range(length - i - 1, i - 1, -1):
47+
if comp(items[j - 1], items[j]):
48+
items[j - 1], items[j] = items[j], items[j - 1]
49+
swapped = True
50+
if not swapped:
51+
break
52+
return items
53+
54+
55+
def merge(list1, list2, comp=lambda x, y: x <= y):
56+
""""有序合并(将两个有序的列表合并成一个新的有序的列表)"""
57+
list3 = []
58+
index1, index2 = 0, 0
59+
while index1 < len(list1) and index2 < len(list2):
60+
if comp(list1[index1], list2[index2]):
61+
list3.append(list1[index1])
62+
index1 += 1
63+
else:
64+
list3.append(list2[index2])
65+
index2 += 1
66+
list3 += list1[index1:]
67+
list3 += list2[index2:]
68+
return list3
69+
70+
71+
def merge_sort(origin_items, comp=lambda x, y: x <= y):
72+
"""归并排序"""
73+
if len(origin_items) <= 1:
74+
return origin_items[:]
75+
mid = len(origin_items) // 2
76+
left = merge_sort(origin_items[:mid], comp)
77+
right = merge_sort(origin_items[mid:], comp)
78+
return merge(left, right, comp)
79+
80+
81+
class Person:
82+
"""人"""
83+
84+
def __init__(self, name, age):
85+
self.name = name
86+
self.age = age
87+
88+
def __repr__(self):
89+
return f'{self.name}: {self.age}'
90+
91+
92+
def main():
93+
# list1 = [12, 35, 48, 87, 92]
94+
# list2 = [39, 44, 50, 60, 77, 88]
95+
# list3 = merge(list1, list2)
96+
# print(list3)
97+
items = [34, 99, 52, 11, 47, 50, 84]
98+
print(items)
99+
print(merge_sort(items))
100+
# items = ['hi', 'hello', 'orange', 'watermelon', 'zoo', 'pitaya']
101+
# items = [
102+
# Person("LuoHao", 38), Person("Baiyuanfang", 25),
103+
# Person("Zhangsanfeng", 120), Person("Lee", 18)
104+
# ]
105+
# new_items = bubble_sort(items, comp=lambda x, y: len(x) > len(y))
106+
# new_items = bubble_sort(items, comp=lambda x, y: x.age > y.age)
107+
# print(items)
108+
# print(new_items)
109+
110+
111+
if __name__ == '__main__':
112+
main()
113+

Day16-20/code/example03.py

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
"""
2+
递归(recursion)
3+
"""
4+
5+
6+
def fac(num):
7+
"""求阶乘"""
8+
if num in (0, 1):
9+
return 1
10+
return num * fac(num - 1)
11+
12+
13+
# 动态规划 - 把求解问题的中间结果保存起来
14+
# 这种算法适合求解有最优子结构的问题或子问题会重复求解的问题
15+
def fib(num, temp={}):
16+
"""计算斐波拉切数"""
17+
# 递归的两个要素
18+
# 收敛条件 - 什么时候结束递归
19+
if num in (1, 2):
20+
return 1
21+
# 递归公式 - 降低问题的求解难度
22+
try:
23+
return temp[num]
24+
except KeyError:
25+
temp[num] = fib(num - 1) + fib(num - 2)
26+
return temp[num]
27+
28+
29+
def fib2(total):
30+
"""斐波拉切数列生成器"""
31+
num1, num2 = 0, 1
32+
for _ in range(total):
33+
num1, num2 = num2, num1 + num2
34+
yield num1
35+
36+
37+
def main():
38+
"""主函数"""
39+
for num in fib2(120):
40+
print(num)
41+
42+
43+
if __name__ == '__main__':
44+
main()

Day16-20/code/example04.py

+145
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
"""
2+
程序设计的范式(理念):
3+
1. 指令式程序设计 - 汇编语言
4+
2. 面向过程程序设计 - 把一组指令封装成一个过程,需要执行这组指令时调用这个过程即可 - C
5+
3. 面向对象程序设计 - 将数据和操作数据的函数从逻辑上组织成了对象 - C++ / Java
6+
4. 函数式程序设计 - 函数是一等对象(一等公民) - Haskell
7+
8+
面向对象程序设计步骤:
9+
1. 定义类 - 抽象过程 - 数据抽象(静态特征-属性)/行为抽象(动态特征-方法)
10+
2. 创建对象 - 构造器 - 初始化(__init__)
11+
3. 给对象发消息 - 对象引用.对象方法(参数)
12+
13+
面向对象的三大支柱 - 封装 / 继承 / 多态
14+
15+
类与类(对象与对象)之间的关系:
16+
1. is-a: 继承
17+
2. has-a: 关联 / 聚合 / 合成
18+
3. use-a: 依赖
19+
20+
面向对象的设计原则/SOLID原则:
21+
1. 单一职责原则 - 类的设计要高内聚
22+
2. 开闭原则 - 接受扩展不接受修改 - 抽象是关键/用继承封装可变性
23+
3. 依赖倒转原则 - 面向抽象编程
24+
4. 里氏替换原则 - 任何时候都可以使用子类型对象替换父类型对象
25+
5. 接口隔离原则
26+
6. 合成聚合复用原则 - 优先考虑用强关联而不是继承去复用代码
27+
7. 最少知识原则(迪米特法则) - 不要跟陌生人讲话
28+
29+
GoF设计模式 - 23种场景(Python中有16中已经被弱化)
30+
- 单例、工厂、原型、适配器、观察者、策略
31+
"""
32+
from enum import Enum
33+
from enum import unique
34+
35+
import random
36+
37+
# 经验: 符号常量优于字面常量
38+
# 枚举类型是定义符号常量的最佳选择
39+
# 如果一个变量的值只有有限多个选项那么最好使用枚举
40+
@unique
41+
class Suite(Enum):
42+
"""花色"""
43+
44+
SPADE = 0
45+
HEART = 1
46+
CLUB = 2
47+
DIAMOND = 3
48+
49+
50+
class Card():
51+
"""牌"""
52+
53+
def __init__(self, suite, face):
54+
self.suite = suite
55+
self.face = face
56+
57+
def show(self):
58+
"""显示牌的花色和点数"""
59+
suites = ['♠️', '♥️', '♣️', '♦️']
60+
faces = [
61+
'', 'A', '2', '3', '4', '5', '6',
62+
'7', '8', '9', '10', 'J', 'Q', 'K'
63+
]
64+
return f'{suites[self.suite.value]} {faces[self.face]}'
65+
66+
def __str__(self):
67+
return self.show()
68+
69+
def __repr__(self):
70+
return self.show()
71+
72+
73+
class Poker():
74+
"""扑克"""
75+
76+
def __init__(self):
77+
self.index = 0
78+
self.cards = [Card(suite, face)
79+
for suite in Suite
80+
for face in range(1, 14)]
81+
82+
def shuffle(self):
83+
"""洗牌"""
84+
random.shuffle(self.cards)
85+
86+
def deal(self):
87+
"""发牌"""
88+
temp = self.cards[self.index]
89+
self.index += 1
90+
return temp
91+
92+
@property
93+
def has_more(self):
94+
"""是否有牌可以发"""
95+
return self.index < len(self.cards)
96+
97+
98+
class Player():
99+
"""玩家"""
100+
101+
def __init__(self, name):
102+
self.name = name
103+
self.cards = []
104+
105+
def get_one(self, card):
106+
"""摸一张牌"""
107+
self.cards.append(card)
108+
109+
def drop_one(self, index):
110+
"""打出一张牌"""
111+
return self.cards.remove(index)
112+
113+
def get_many(self, more_cards):
114+
"""摸多张牌"""
115+
self.cards += more_cards
116+
117+
def drop_cards(self):
118+
"""扔掉所有牌"""
119+
self.cards.clear()
120+
121+
def arrange(self):
122+
"""整理手上的牌"""
123+
self.cards.sort(key=lambda x: (x.suite.value, x.face))
124+
125+
126+
def main():
127+
"""主函数"""
128+
poker = Poker()
129+
poker.shuffle()
130+
players = [
131+
Player("东邪"), Player("西毒"),
132+
Player("南帝"), Player("北丐")
133+
]
134+
for _ in range(3):
135+
for player in players:
136+
if poker.has_more:
137+
player.get_one(poker.deal())
138+
for player in players:
139+
player.arrange()
140+
print(player.name)
141+
print(player.cards)
142+
143+
144+
if __name__ == '__main__':
145+
main()

Day16-20/code/example05.py

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
"""
2+
设计模式 - 策略模式(指定的策略不同执行的算法不同)
3+
"""
4+
from hashlib import md5
5+
from hashlib import sha1
6+
from hashlib import sha256
7+
from hashlib import sha512
8+
9+
10+
class StreamHasher():
11+
"""哈希摘要生成器"""
12+
13+
def __init__(self, algorithm='md5', size=1024):
14+
self.size = size
15+
alg = algorithm.lower()
16+
if alg == 'md5':
17+
self.hasher = md5()
18+
elif alg == 'sha1':
19+
self.hasher = sha1()
20+
elif alg == 'sha256':
21+
self.hasher = sha256()
22+
elif alg == 'sha512':
23+
self.hasher = sha512()
24+
else:
25+
raise ValueError('不支持指定的摘要算法')
26+
27+
# 魔法方法: 让对象可以像函数一样被调用
28+
def __call__(self, stream):
29+
return self.to_digest(stream)
30+
31+
def to_digest(self, stream):
32+
"""生成十六进制形式的哈希摘要字符串"""
33+
for data in iter(lambda: stream.read(self.size), b''):
34+
self.hasher.update(data)
35+
return self.hasher.hexdigest()
36+
37+
38+
def main():
39+
"""主函数"""
40+
hasher = StreamHasher('sha1', 4096)
41+
with open('Python语言规范.pdf', 'rb') as stream:
42+
# print(hasher.to_digest(stream))
43+
print(hasher(stream))
44+
45+
46+
if __name__ == '__main__':
47+
main()

0 commit comments

Comments
 (0)