Commit 6a7f8602 authored by jackfrued's avatar jackfrued

调整了目录结构

parent 36ffd6c2
......@@ -6,7 +6,7 @@
### for-in循环
如果明确的知道循环执行的次数或者是要对一个容器进行迭代(后面会讲到),那么我们推荐使用`for-in`循环,例如下面代码中计算![$\sum_{n=1}^{100}n$](./res/formula_1.png)
如果明确的知道循环执行的次数或者是要对一个容器进行迭代(后面会讲到),那么我们推荐使用`for-in`循环,例如下面代码中计算![$\sum_{n=1}^{100}n$](./res/formula_2.png)
```Python
"""
......
......@@ -2,11 +2,11 @@
在讲解本章节的内容之前,我们先来研究一道数学题,请说出下面的方程有多少组正整数解。
![$$x_1 + x_2 + x_3 + x_4 = 8$$](./res/formula_1.png)
![$$x_1 + x_2 + x_3 + x_4 = 8$$](./res/formula_3.png)
事实上,上面的问题等同于将8个苹果分成四组每组至少一个苹果有多少种方案。想到这一点问题的答案就呼之欲出了。
![$$C_M^N =\frac{M!}{N!(M-N)!}, \text{(M=7, N=3)} $$](./res/formula_2.png)
![$$C_M^N =\frac{M!}{N!(M-N)!}, \text{(M=7, N=3)} $$](./res/formula_4.png)
可以用Python的程序来计算出这个值,代码如下所示。
......
......@@ -2,7 +2,7 @@
### 使用字符串
第二次世界大战促使了现代电子计算机的诞生,当初的想法很简单,就是用计算机来计算导弹的弹道,因此在计算机刚刚诞生的那个年代,计算机处理的信息主要是数值,而世界上的第一台电子计算机ENIAC每秒钟能够完成约5000次浮点运算。随着时间的推移,虽然对数值运算仍然是计算机日常工作中最为重要的事情之一,但是今天的计算机处理得更多的数据都是以文本信息的方式存在的,而Python表示文本信息的方式我们在很早以前就说过了,那就是字符串类型。所谓**字符串**,就是由零个或多个字符组成的有限序列,一般记为![$${\displaystyle s=a_{1}a_{2}\dots a_{n}(0\leq n \leq \infty)}$$](./res/formula_1.png)
第二次世界大战促使了现代电子计算机的诞生,当初的想法很简单,就是用计算机来计算导弹的弹道,因此在计算机刚刚诞生的那个年代,计算机处理的信息主要是数值,而世界上的第一台电子计算机ENIAC每秒钟能够完成约5000次浮点运算。随着时间的推移,虽然对数值运算仍然是计算机日常工作中最为重要的事情之一,但是今天的计算机处理得更多的数据都是以文本信息的方式存在的,而Python表示文本信息的方式我们在很早以前就说过了,那就是字符串类型。所谓**字符串**,就是由零个或多个字符组成的有限序列,一般记为![$${\displaystyle s=a_{1}a_{2}\dots a_{n}(0\leq n \leq \infty)}$$](./res/formula_5.png)
我们可以通过下面的代码来了解字符串的使用。
......@@ -183,11 +183,11 @@ if __name__ == '__main__':
除了上面提到的生成器语法,Python中还有另外一种定义生成器的方式,就是通过`yield`关键字将一个普通函数改造成生成器函数。下面的代码演示了如何实现一个生成[斐波拉切数列](https://zh.wikipedia.org/wiki/%E6%96%90%E6%B3%A2%E9%82%A3%E5%A5%91%E6%95%B0%E5%88%97)的生成器。所谓斐波拉切数列可以通过下面[递归](https://zh.wikipedia.org/wiki/%E9%80%92%E5%BD%92)的方法来进行定义:
![$${\displaystyle F_{0}=0}$$](./res/formula_2.png)
![$${\displaystyle F_{0}=0}$$](./res/formula_6.png)
![$${\displaystyle F_{1}=1}$$](./res/formula_3.png)
![$${\displaystyle F_{1}=1}$$](./res/formula_7.png)
![$${\displaystyle F_{n}=F_{n-1}+F_{n-2}}({n}\geq{2})$$](./res/formula_4.png)
![$${\displaystyle F_{n}=F_{n-1}+F_{n-2}}({n}\geq{2})$$](./res/formula_8.png)
![](./res/fibonacci-blocks.png)
......
......@@ -297,3 +297,123 @@ if __name__ == '__main__':
传输层除了有可靠的传输协议TCP之外,还有一种非常轻便的传输协议叫做用户数据报协议,简称UDP。TCP和UDP都是提供端到端传输服务的协议,二者的差别就如同打电话和发短信的区别,后者不对传输的可靠性和可达性做出任何承诺从而避免了TCP中握手和重传的开销,所以在强调性能和而不是数据完整性的场景中(例如传输网络音视频数据),UDP可能是更好的选择。可能大家会注意到一个现象,就是在观看网络视频时,有时会出现卡顿,有时会出现花屏,这无非就是部分数据传丢或传错造成的。在Python中也可以使用UDP套接字来创建网络应用,对此我们不进行赘述,有兴趣的读者可以自行研究。
### 网络应用开发
#### 发送电子邮件
在即时通信软件如此发达的今天,电子邮件仍然是互联网上使用最为广泛的应用之一,公司向应聘者发出录用通知、网站向用户发送一个激活账号的链接、银行向客户推广它们的理财产品等几乎都是通过电子邮件来完成的,而这些任务应该都是由程序自动完成的。
就像我们可以用HTTP(超文本传输协议)来访问一个网站一样,发送邮件要使用SMTP(简单邮件传输协议),SMTP也是一个建立在TCP(传输控制协议)提供的可靠数据传输服务的基础上的应用级协议,它规定了邮件的发送者如何跟发送邮件的服务器进行通信的细节,而Python中的smtplib模块将这些操作简化成了几个简单的函数。
下面的代码演示了如何在Python发送邮件。
```Python
from smtplib import SMTP
from email.header import Header
from email.mime.text import MIMEText
def main():
# 请自行修改下面的邮件发送者和接收者
sender = 'abcdefg@126.com'
receivers = ['uvwxyz@qq.com', 'uvwxyz@126.com']
message = MIMEText('用Python发送邮件的示例代码.', 'plain', 'utf-8')
message['From'] = Header('王大锤', 'utf-8')
message['To'] = Header('骆昊', 'utf-8')
message['Subject'] = Header('示例代码实验邮件', 'utf-8')
smtper = SMTP('smtp.126.com')
# 请自行修改下面的登录口令
smtper.login(sender, 'secretpass')
smtper.sendmail(sender, receivers, message.as_string())
print('邮件发送完成!')
if __name__ == '__main__':
main()
```
如果要发送带有附件的邮件,那么可以按照下面的方式进行操作。
```Python
from smtplib import SMTP
from email.header import Header
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
import urllib
def main():
# 创建一个带附件的邮件消息对象
message = MIMEMultipart()
# 创建文本内容
text_content = MIMEText('附件中有本月数据请查收', 'plain', 'utf-8')
message['Subject'] = Header('本月数据', 'utf-8')
# 将文本内容添加到邮件消息对象中
message.attach(text_content)
# 读取文件并将文件作为附件添加到邮件消息对象中
with open('/Users/Hao/Desktop/hello.txt', 'rb') as f:
txt = MIMEText(f.read(), 'base64', 'utf-8')
txt['Content-Type'] = 'text/plain'
txt['Content-Disposition'] = 'attachment; filename=hello.txt'
message.attach(txt)
# 读取文件并将文件作为附件添加到邮件消息对象中
with open('/Users/Hao/Desktop/汇总数据.xlsx', 'rb') as f:
xls = MIMEText(f.read(), 'base64', 'utf-8')
xls['Content-Type'] = 'application/vnd.ms-excel'
xls['Content-Disposition'] = 'attachment; filename=month-data.xlsx'
message.attach(xls)
# 创建SMTP对象
smtper = SMTP('smtp.126.com')
# 开启安全连接
# smtper.starttls()
sender = 'abcdefg@126.com'
receivers = ['uvwxyz@qq.com']
# 登录到SMTP服务器
# 请注意此处不是使用密码而是邮件客户端授权码进行登录
# 对此有疑问的读者可以联系自己使用的邮件服务器客服
smtper.login(sender, 'secretpass')
# 发送邮件
smtper.sendmail(sender, receivers, message.as_string())
# 与邮件服务器断开连接
smtper.quit()
print('发送完成!')
if __name__ == '__main__':
main()
```
#### 发送短信
发送短信也是项目中常见的功能,网站的注册码、验证码、营销信息基本上都是通过短信来发送给用户的。在下面的代码中我们使用了[互亿无线](http://www.ihuyi.com/)短信平台(该平台为注册用户提供了50条免费短信以及常用开发语言发送短信的demo,可以登录该网站并在用户自服务页面中对短信进行配置)提供的API接口实现了发送短信的服务,当然国内的短信平台很多,读者可以根据自己的需要进行选择(通常会考虑费用预算、短信达到率、使用的难易程度等指标),如果需要在商业项目中使用短信服务建议购买短信平台提供的套餐服务。
```Python
import urllib.parse
import http.client
import json
def main():
host = "106.ihuyi.com"
sms_send_uri = "/webservice/sms.php?method=Submit"
# 下面的参数需要填入自己注册的账号和对应的密码
params = urllib.parse.urlencode({'account': '你自己的账号', 'password' : '你自己的密码', 'content': '您的验证码是:147258。请不要把验证码泄露给其他人。', 'mobile': '接收者的手机号', 'format':'json' })
print(params)
headers = {'Content-type': 'application/x-www-form-urlencoded', 'Accept': 'text/plain'}
conn = http.client.HTTPConnection(host, port=80, timeout=30)
conn.request('POST', sms_send_uri, params, headers)
response = conn.getresponse()
response_str = response.read()
jsonstr = response_str.decode('utf-8')
print(json.loads(jsonstr))
conn.close()
if __name__ == '__main__':
main()
```
\ No newline at end of file
This diff is collapsed.
## 网络应用开发
### 发送电子邮件
在即时通信软件如此发达的今天,电子邮件仍然是互联网上使用最为广泛的应用之一,公司向应聘者发出录用通知、网站向用户发送一个激活账号的链接、银行向客户推广它们的理财产品等几乎都是通过电子邮件来完成的,而这些任务应该都是由程序自动完成的。
就像我们可以用HTTP(超文本传输协议)来访问一个网站一样,发送邮件要使用SMTP(简单邮件传输协议),SMTP也是一个建立在TCP(传输控制协议)提供的可靠数据传输服务的基础上的应用级协议,它规定了邮件的发送者如何跟发送邮件的服务器进行通信的细节,而Python中的smtplib模块将这些操作简化成了几个简单的函数。
下面的代码演示了如何在Python发送邮件。
```Python
from smtplib import SMTP
from email.header import Header
from email.mime.text import MIMEText
def main():
# 请自行修改下面的邮件发送者和接收者
sender = 'abcdefg@126.com'
receivers = ['uvwxyz@qq.com', 'uvwxyz@126.com']
message = MIMEText('用Python发送邮件的示例代码.', 'plain', 'utf-8')
message['From'] = Header('王大锤', 'utf-8')
message['To'] = Header('骆昊', 'utf-8')
message['Subject'] = Header('示例代码实验邮件', 'utf-8')
smtper = SMTP('smtp.126.com')
# 请自行修改下面的登录口令
smtper.login(sender, 'secretpass')
smtper.sendmail(sender, receivers, message.as_string())
print('邮件发送完成!')
if __name__ == '__main__':
main()
```
如果要发送带有附件的邮件,那么可以按照下面的方式进行操作。
```Python
from smtplib import SMTP
from email.header import Header
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
import urllib
def main():
# 创建一个带附件的邮件消息对象
message = MIMEMultipart()
# 创建文本内容
text_content = MIMEText('附件中有本月数据请查收', 'plain', 'utf-8')
message['Subject'] = Header('本月数据', 'utf-8')
# 将文本内容添加到邮件消息对象中
message.attach(text_content)
# 读取文件并将文件作为附件添加到邮件消息对象中
with open('/Users/Hao/Desktop/hello.txt', 'rb') as f:
txt = MIMEText(f.read(), 'base64', 'utf-8')
txt['Content-Type'] = 'text/plain'
txt['Content-Disposition'] = 'attachment; filename=hello.txt'
message.attach(txt)
# 读取文件并将文件作为附件添加到邮件消息对象中
with open('/Users/Hao/Desktop/汇总数据.xlsx', 'rb') as f:
xls = MIMEText(f.read(), 'base64', 'utf-8')
xls['Content-Type'] = 'application/vnd.ms-excel'
xls['Content-Disposition'] = 'attachment; filename=month-data.xlsx'
message.attach(xls)
# 创建SMTP对象
smtper = SMTP('smtp.126.com')
# 开启安全连接
# smtper.starttls()
sender = 'abcdefg@126.com'
receivers = ['uvwxyz@qq.com']
# 登录到SMTP服务器
# 请注意此处不是使用密码而是邮件客户端授权码进行登录
# 对此有疑问的读者可以联系自己使用的邮件服务器客服
smtper.login(sender, 'secretpass')
# 发送邮件
smtper.sendmail(sender, receivers, message.as_string())
# 与邮件服务器断开连接
smtper.quit()
print('发送完成!')
if __name__ == '__main__':
main()
```
### 发送短信
发送短信也是项目中常见的功能,网站的注册码、验证码、营销信息基本上都是通过短信来发送给用户的。在下面的代码中我们使用了[互亿无线](http://www.ihuyi.com/)短信平台(该平台为注册用户提供了50条免费短信以及常用开发语言发送短信的demo,可以登录该网站并在用户自服务页面中对短信进行配置)提供的API接口实现了发送短信的服务,当然国内的短信平台很多,读者可以根据自己的需要进行选择(通常会考虑费用预算、短信达到率、使用的难易程度等指标),如果需要在商业项目中使用短信服务建议购买短信平台提供的套餐服务。
```Python
import urllib.parse
import http.client
import json
def main():
host = "106.ihuyi.com"
sms_send_uri = "/webservice/sms.php?method=Submit"
# 下面的参数需要填入自己注册的账号和对应的密码
params = urllib.parse.urlencode({'account': '你自己的账号', 'password' : '你自己的密码', 'content': '您的验证码是:147258。请不要把验证码泄露给其他人。', 'mobile': '接收者的手机号', 'format':'json' })
print(params)
headers = {'Content-type': 'application/x-www-form-urlencoded', 'Accept': 'text/plain'}
conn = http.client.HTTPConnection(host, port=80, timeout=30)
conn.request('POST', sms_send_uri, params, headers)
response = conn.getresponse()
response_str = response.read()
jsonstr = response_str.decode('utf-8')
print(json.loads(jsonstr))
conn.close()
if __name__ == '__main__':
main()
```
import pygame
EMPTY = 0
BLACK = 1
WHITE = 2
black_color = [0, 0, 0]
white_color = [255, 255, 255]
class RenjuBoard(object):
def __init__(self):
self._board = [[]] * 15
self.reset()
def reset(self):
for row in range(len(self._board)):
self._board[row] = [EMPTY] * 15
def move(self, row, col, is_black):
if self._board[row][col] == EMPTY:
self._board[row][col] = BLACK if is_black else WHITE
return True
return False
def draw(self, screen):
for index in range(1, 16):
pygame.draw.line(screen, black_color,
[40, 40 * index], [600, 40 * index], 1)
pygame.draw.line(screen, black_color,
[40 * index, 40], [40 * index, 600], 1)
pygame.draw.rect(screen, black_color, [36, 36, 568, 568], 4)
pygame.draw.circle(screen, black_color, [320, 320], 5, 0)
pygame.draw.circle(screen, black_color, [160, 160], 5, 0)
pygame.draw.circle(screen, black_color, [480, 480], 5, 0)
pygame.draw.circle(screen, black_color, [480, 160], 5, 0)
pygame.draw.circle(screen, black_color, [160, 480], 5, 0)
for row in range(len(self._board)):
for col in range(len(self._board[row])):
if self._board[row][col] != EMPTY:
ccolor = black_color \
if self._board[row][col] == BLACK else white_color
pos = [40 * (col + 1), 40 * (row + 1)]
pygame.draw.circle(screen, ccolor, pos, 20, 0)
def main():
board = RenjuBoard()
is_black = True
pygame.init()
pygame.display.set_caption('五子棋')
screen = pygame.display.set_mode([640, 640])
screen.fill([255, 255, 0])
board.draw(screen)
pygame.display.flip()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYUP:
pass
elif event.type == pygame.MOUSEBUTTONDOWN\
and event.button == 1:
x, y = event.pos
row = round((y - 40) / 40)
col = round((x - 40) / 40)
if board.move(row, col, is_black):
is_black = not is_black
screen.fill([255, 255, 0])
board.draw(screen)
pygame.display.flip()
pygame.quit()
if __name__ == '__main__':
main()
import pygame
EMPTY = 0
BLACK = 1
WHITE = 2
black_color = [0, 0, 0]
white_color = [255, 255, 255]
class RenjuBoard(object):
def __init__(self):
self._board = [[]] * 15
self.reset()
def reset(self):
for row in range(len(self._board)):
self._board[row] = [EMPTY] * 15
def move(self, row, col, is_black):
if self._board[row][col] == EMPTY:
self._board[row][col] = BLACK if is_black else WHITE
return True
return False
def draw(self, screen):
for index in range(1, 16):
pygame.draw.line(screen, black_color,
[40, 40 * index], [600, 40 * index], 1)
pygame.draw.line(screen, black_color,
[40 * index, 40], [40 * index, 600], 1)
pygame.draw.rect(screen, black_color, [36, 36, 568, 568], 4)
pygame.draw.circle(screen, black_color, [320, 320], 5, 0)
pygame.draw.circle(screen, black_color, [160, 160], 5, 0)
pygame.draw.circle(screen, black_color, [480, 480], 5, 0)
pygame.draw.circle(screen, black_color, [480, 160], 5, 0)
pygame.draw.circle(screen, black_color, [160, 480], 5, 0)
for row in range(len(self._board)):
for col in range(len(self._board[row])):
if self._board[row][col] != EMPTY:
ccolor = black_color \
if self._board[row][col] == BLACK else white_color
pos = [40 * (col + 1), 40 * (row + 1)]
pygame.draw.circle(screen, ccolor, pos, 20, 0)
def main():
board = RenjuBoard()
is_black = True
pygame.init()
pygame.display.set_caption('五子棋')
screen = pygame.display.set_mode([640, 640])
screen.fill([255, 255, 0])
board.draw(screen)
pygame.display.flip()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYUP:
pass
elif event.type == pygame.MOUSEBUTTONDOWN\
and event.button == 1:
x, y = event.pos
row = round((y - 40) / 40)
col = round((x - 40) / 40)
if board.move(row, col, is_black):
is_black = not is_black
screen.fill([255, 255, 0])
board.draw(screen)
pygame.display.flip()
pygame.quit()
if __name__ == '__main__':
main()
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment