更新了部分文档
parent
7a89e21efc
commit
cc537bd125
|
@ -11,10 +11,7 @@ import random
|
||||||
@unique
|
@unique
|
||||||
class Suite(Enum):
|
class Suite(Enum):
|
||||||
"""花色(枚举)"""
|
"""花色(枚举)"""
|
||||||
SPADE = 0
|
SPADE, HEART, CLUB, DIAMOND = range(4)
|
||||||
HEART = 1
|
|
||||||
CLUB = 2
|
|
||||||
DIAMOND = 3
|
|
||||||
|
|
||||||
def __lt__(self, other):
|
def __lt__(self, other):
|
||||||
return self.value < other.value
|
return self.value < other.value
|
||||||
|
|
|
@ -1,2 +1,9 @@
|
||||||
## 前后端分离开发
|
## 前后端分离开发
|
||||||
|
|
||||||
|
在传统的Web应用开发中,大多数的程序员会将浏览器作为前后端的分界线。将浏览器中为用户进行页面展示的部分称之为前端,而将运行在服务器,为前端提供业务逻辑和数据准备的所有代码统称为后端。所谓前后端分离的开发,就是前后端工程师约定好数据交互接口,并行的进行开发和测试,后端只提供数据,不负责将数据渲染到页面上,前端通过HTTP请求获取数据并负责将数据渲染到页面上,这个工作是交给浏览器中的JavaScript代码来完成。
|
||||||
|
|
||||||
|
使用前后端分离开发有诸多的好处,下面我们简要的说下这些好处:
|
||||||
|
|
||||||
|
1. **提升开发效率**。前后端分离以后,可以实现前后端代码的解耦,只要前后端沟通约定好应用所需接口以及接口参数,便可以开始并行开发,无需等待对方的开发工作结束。在这种情况下,前后端工程师都可以只专注于自己的开发工作,有助于打造出更好的团队。除此之外,在前后端分离的开发模式下,即使需求发生变更,只要接口与数据格式不变,后端开发人员就不需要修改代码,只要前端进行变动即可。
|
||||||
|
2. **增强代码的可维护性**。前后端分离后,应用的代码不再是前后端混合,只有在运行期才会有调用依赖关系,这样的话维护代码的工作将变得轻松愉快很多,再不会牵一发而动全身。当你的代码变得简明且整洁时,代码的可读性和可维护性都会有质的提升。
|
||||||
|
3. **支持多终端和服务化架构**。前后端分离后,同一套数据接口可以为不同的终端提供服务,更有助于打造多终端应用;此外,由于后端提供的接口之间可以通过HTTP进行调用,有助于打造服务化架构(包括微服务)。
|
|
@ -55,35 +55,30 @@
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
2. URL参数和请求头。
|
2. URL参数和请求头。
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
3. 复杂的POST请求(文件上传)。
|
3. 复杂的POST请求(文件上传)。
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
4. 操作Cookie。
|
4. 操作Cookie。
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
5. 设置代理服务器。
|
5. 设置代理服务器。
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
> 说明:关于requests的详细用法可以参考它的[官方文档](http://docs.python-requests.org/zh_CN/latest/user/quickstart.html)。
|
> 说明:关于requests的详细用法可以参考它的[官方文档](http://docs.python-requests.org/zh_CN/latest/user/quickstart.html)。
|
||||||
|
@ -92,14 +87,14 @@
|
||||||
|
|
||||||
#### 四种采集方式的比较
|
#### 四种采集方式的比较
|
||||||
|
|
||||||
| 抓取方法 | 速度 | 使用难度 | 备注 |
|
| 抓取方法 | 速度 | 使用难度 | 备注 |
|
||||||
| ---------- | ------------------------- | -------- | ------------------------------------------ |
|
| ------------- | ------------------------- | -------- | ------------------------------------------ |
|
||||||
| 正则表达式 | 快 | 困难 | 常用正则表达式<br>在线正则表达式测试 |
|
| 正则表达式 | 快 | 困难 | 常用正则表达式<br>在线正则表达式测试 |
|
||||||
| lxml | 快 | 一般 | 需要安装C语言依赖库<br>唯一支持XML的解析器 |
|
| lxml | 快 | 一般 | 需要安装C语言依赖库<br>唯一支持XML的解析器 |
|
||||||
| Beautiful | 较快/较慢(取决于解析器) | 简单 | |
|
| BeautifulSoup | 较快/较慢(取决于解析器) | 简单 | |
|
||||||
| PyQuery | 较快 | 简单 | Python版的jQuery |
|
| PyQuery | 较快 | 简单 | Python版的jQuery |
|
||||||
|
|
||||||
> 说明:Beautiful的解析器包括:Python标准库(html.parser)、lxml的HTML解析器、lxml的XML解析器和html5lib。
|
> 说明:BeautifulSoup可选的解析器包括:Python标准库(html.parser)、lxml的HTML解析器、lxml的XML解析器和html5lib。
|
||||||
|
|
||||||
#### 使用正则表达式
|
#### 使用正则表达式
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
> 作者:骆昊
|
> 作者:骆昊
|
||||||
>
|
>
|
||||||
> 说明:最近有很多想学习Python的小伙伴申请单独加我微信和QQ,因为我自己平时也很忙,没办法一一解答大家的问题,我创建了**Python100天学习交流6群**(之前的两个2000人群1群和2群、两个1000人群3群和4群已经全部满员),群号为**837590310**,二维码在下方。我的同事和朋友也在这个群里,他们很多都是优秀的Python开发者,有丰富的商业项目经验,我们在时间充足的时候会及时解答大家的问题,从Python语言入门到Web应用开发,从数据分析到机器学习,每个领域都有技术大咖为大家解惑答疑。以后我们争取每周做一次视频直播,以专题的形式分享Python开发的点点滴滴,同时还会不定期的举办线上和线下的技术交流和分享活动,小伙伴们可以加群进行交流。创作不易,感谢各位小伙伴的打赏支持,也感谢**千锋教育Python教学部**对QQ群的支持。
|
> 说明:最近有很多想学习Python的小伙伴申请单独加我微信和QQ,因为我自己平时也很忙,没办法一一解答大家的问题,我创建了**Python100天学习交流6群**(之前的两个2000人群1群和2群、三个1000人群3群、4群、5群已经全部满员),群号为**837590310**,二维码在下方。我的同事和朋友也在这个群里,他们很多都是优秀的Python开发者,有丰富的商业项目经验,我们在时间充足的时候会及时解答大家的问题,从Python语言入门到Web应用开发,从数据分析到机器学习,每个领域都有技术大咖为大家解惑答疑。以后我们争取每周做一次视频直播,以专题的形式分享Python开发的点点滴滴,同时还会不定期的举办线上和线下的技术交流和分享活动,小伙伴们可以加群进行交流。创作不易,感谢各位小伙伴的打赏支持,也感谢**千锋教育Python教学部**对QQ群的支持。
|
||||||
|
|
||||||
![](./res/python_100_days_qq_group.png)
|
![](./res/python_100_days_qq_group.png)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,158 @@
|
||||||
|
## 算法入门系列课程1 - 周而复始
|
||||||
|
|
||||||
|
### 算法概述
|
||||||
|
|
||||||
|
1. 什么是算法?
|
||||||
|
|
||||||
|
解决问题的正确方法和具体的实施步骤。
|
||||||
|
|
||||||
|
例子1:如何在两栋相距50m的大楼的两个房间牵一条线(两个房间都有窗)?
|
||||||
|
|
||||||
|
- 养一只鸟(如鸽子),将线送过去
|
||||||
|
- 用很长的杆子将线递过去
|
||||||
|
- 用无人机(遥控飞行器)将线送过去
|
||||||
|
|
||||||
|
如何评价这些方法的好坏?**少花钱,不费事**!
|
||||||
|
|
||||||
|
例子2:大教室里坐了几百名学生一起听课,如何快速的统计学生人数?
|
||||||
|
|
||||||
|
例子3:向列表容器中**逆向**插入100000个元素。
|
||||||
|
|
||||||
|
- 方法1:
|
||||||
|
|
||||||
|
```Python
|
||||||
|
nums = []
|
||||||
|
for i in range(100000):
|
||||||
|
nums.append(i)
|
||||||
|
nums.reverse()
|
||||||
|
```
|
||||||
|
|
||||||
|
- 方法2:
|
||||||
|
|
||||||
|
```Python
|
||||||
|
nums = []
|
||||||
|
for i in range(100000):
|
||||||
|
nums.insert(0, i)
|
||||||
|
```
|
||||||
|
|
||||||
|
例子3:生成Fibonacci数列(前100个Fibonacci数)。
|
||||||
|
|
||||||
|
- 方法1 - 递推:
|
||||||
|
|
||||||
|
```Python
|
||||||
|
a, b = 0, 1
|
||||||
|
for num in range(1, 101):
|
||||||
|
a, b = b, a + b
|
||||||
|
print(f'{num}: {a}')
|
||||||
|
```
|
||||||
|
|
||||||
|
- 方法2 - 递归:
|
||||||
|
|
||||||
|
```Python
|
||||||
|
def fib(num):
|
||||||
|
if num in (1, 2):
|
||||||
|
return 1
|
||||||
|
return fib(num - 1) + fib(num - 2)
|
||||||
|
|
||||||
|
|
||||||
|
for num in range(1, 101):
|
||||||
|
print(f'{num}: {fib(num)}')
|
||||||
|
```
|
||||||
|
|
||||||
|
- 方法3 - 改进的递归:
|
||||||
|
|
||||||
|
```Python
|
||||||
|
def fib(num, temp={}):
|
||||||
|
if num in (1, 2):
|
||||||
|
return 1
|
||||||
|
elif num not in temp:
|
||||||
|
temp[num] = fib(num - 1) + fib(num - 2)
|
||||||
|
return temp[num]
|
||||||
|
```
|
||||||
|
|
||||||
|
- 方法4 - 改进的递归:
|
||||||
|
|
||||||
|
```Python
|
||||||
|
from functools import lru_cache
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache()
|
||||||
|
def fib(num):
|
||||||
|
if num in (1, 2):
|
||||||
|
return 1
|
||||||
|
return fib(num - 1) + fib(num - 2)
|
||||||
|
```
|
||||||
|
|
||||||
|
2. 如何评价算法的好坏?
|
||||||
|
|
||||||
|
[渐近时间复杂度](<https://zh.wikipedia.org/wiki/%E6%97%B6%E9%97%B4%E5%A4%8D%E6%9D%82%E5%BA%A6>)和渐近空间复杂度。
|
||||||
|
|
||||||
|
3. 大***O***符号的意义?
|
||||||
|
|
||||||
|
表示一个函数相对于输入规模的增长速度,也可以称之为函数的数量级。
|
||||||
|
|
||||||
|
| 大*O*符号 | 说明 | 例子 |
|
||||||
|
| --------------- | ------------------ | -------------------------------------------- |
|
||||||
|
| $$O(c)$$ | 常量时间复杂度 | 布隆过滤器 / 哈希存储 |
|
||||||
|
| $$O(log_2n)$$ | 对数时间复杂度 | 二分查找(折半查找) |
|
||||||
|
| $$O(n)$$ | 线性时间复杂度 | 顺序查找 / 桶排序 |
|
||||||
|
| $$O(n*log_2n)$$ | 对数线性时间复杂度 | 高级排序算法(归并排序、快速排序) |
|
||||||
|
| $$O(n^2)$$ | 平方时间复杂度 | 简单排序算法(选择排序、插入排序、冒泡排序) |
|
||||||
|
| $$O(n^3)$$ | 立方时间复杂度 | Floyd算法 / 矩阵乘法运算 |
|
||||||
|
| $$O(2^n)$$ | 几何级数时间复杂度 | 汉诺塔 |
|
||||||
|
| $$O(n!)$$ | 阶乘时间复杂度 | 旅行经销商问题 |
|
||||||
|
|
||||||
|
### 穷举法
|
||||||
|
|
||||||
|
在计算机科学中,**穷举法**或者**暴力搜索法**是一个非常非常直观的解决问题的方法,这种方法通过一项一项的列举解决方案所有可能的候选项以及检查每个候选项是否符合问题的描述,最终得到问题的解。
|
||||||
|
|
||||||
|
虽然暴力搜索很容易实现,并且如果解决方案存在它就一定能够找到,但是它的代价是和候选方案的数量成比例的,由于这一点,在很多实际问题中,消耗的代价会随着问题规模的增加而快速地增长。因此,当问题规模有限或当存在可用于将候选解决方案的集合减少到可管理大小时,就可以使用暴力搜索。另外,当实现方法的简单度比速度更重要的时候,也可以考虑使用这种方法。
|
||||||
|
|
||||||
|
### 经典例子
|
||||||
|
|
||||||
|
1. **百钱百鸡**问题:公鸡5元一只,母鸡3元一只,小鸡1元三只,用100元买一百只鸡,问公鸡、母鸡、小鸡各有多少只?
|
||||||
|
|
||||||
|
```Python
|
||||||
|
for x in range(21):
|
||||||
|
for y in range(34):
|
||||||
|
z = 100 - x - y
|
||||||
|
if z % 3 == 0 and 5 * x + 3 * y + z // 3 == 100:
|
||||||
|
print(x, y, z)
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **五人分鱼**问题:ABCDE五人在某天夜里合伙捕鱼,最后疲惫不堪各自睡觉。第二天A第一个醒来,他将鱼分为5份,扔掉多余的1条,拿走了属于自己的一份;B第二个醒来,也将鱼分为5份,扔掉多余的1条,拿走属于自己的一份;然后C、D、E依次醒来,也按同样的方式分鱼,问他们至少捕了多少条鱼?
|
||||||
|
|
||||||
|
```Python
|
||||||
|
fish = 6
|
||||||
|
while True:
|
||||||
|
total = fish
|
||||||
|
enough = True
|
||||||
|
for _ in range(5):
|
||||||
|
if (total - 1) % 5 == 0:
|
||||||
|
total = (total - 1) // 5 * 4
|
||||||
|
else:
|
||||||
|
enough = False
|
||||||
|
break
|
||||||
|
if enough:
|
||||||
|
print(fish)
|
||||||
|
break
|
||||||
|
fish += 5
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **暴力破解口令**:
|
||||||
|
|
||||||
|
```Python
|
||||||
|
import re
|
||||||
|
|
||||||
|
import PyPDF2
|
||||||
|
|
||||||
|
with open('Python_Tricks_encrypted.pdf', 'rb') as pdf_file_stream:
|
||||||
|
reader = PyPDF2.PdfFileReader(pdf_file_stream)
|
||||||
|
with open('dictionary.txt', 'r') as txt_file_stream:
|
||||||
|
file_iter = iter(lambda: txt_file_stream.readline(), '')
|
||||||
|
for word in file_iter:
|
||||||
|
word = re.sub(r'\s', '', word)
|
||||||
|
if reader.decrypt(word):
|
||||||
|
print(word)
|
||||||
|
break
|
||||||
|
```
|
|
@ -1 +1 @@
|
||||||
链接:https://pan.baidu.com/s/1YMFb-dv8pHAfeSPXQoDoHA 密码:obdu
|
链接:https://pan.baidu.com/s/1PuevYD_A0c1DgJbyeAycHA 密码:l2nd
|
Loading…
Reference in New Issue