slacr_

Just to record my life and thoughts.
笔记/编程/杂乱/极简

[Python]基础

Sep 6, 2023Python10059 words in 67 min

keep practicing and practicing

python 用作计算器

  • _ 指代上一次计算结果
  • ""或'' 操作字符串, 表示引号本身使用 \ 转义, 不希望转义, 在字符串前加r
  • 多行字符串字面量使用三重引号, \可将两行连接
  • 字符串使用+拼接, *重复, 相邻的两个或多个 字符串字面值 (引号标注的字符)会自动合并
  • 使用[a:b] 索引字符串, 左闭右开, python字符串不可改, 要生成不同字符串应新建
  • 列表和字符串一样支持索引和切片, 还支持合并+, 可更改
1
2
3
4
5
# fibonacci series
a, b = 0, 1
while a < 100:
print(a, end=" ")
a, b = b, a+b

查询关键字/保留字

1
2
import keyword 
print(keyword.kwlist)
1
2
3
4
5
6
7
8
9
10
# TempConvert
TempStr = input("What is the temperature?")
if TempStr[-1] in ['F', 'f']:
C = round((eval(TempStr[0:-1]) - 32) / 1.8)
print("The converted temperature is {:}C".format(C))
elif TempStr[-1] in ['C', 'c']:
F = round(1.8*eval(TempStr[0:-1]) + 32)
print("The converted temperature is {:}F".format(F))
else:
print("input error")

eval()

eval函数将字符串转换为数值
m = eval(input("string"))
如果无eval函数, m 将被解释成字符串, 因为input获取用户输入的结果是字符串.

import

  1. import libName
  2. from libName import <funcName1, ...> * 通配符表示所有函数, 这种调用时不用指定库名

turtle绘制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import turtle
def drawSnake(radius, angle,length):
turtle.seth(-40)
for i in range(length):
turtle.circle(radius, angle)
turtle.circle(-radius, angle)
turtle.circle(radius, angle/2)
turtle.fd(40)
turtle.circle(40,180)
turtle.fd(40* 2/3)
turtle.setup(650,350,200,200)
turtle.penup()
turtle.fd(-250)
turtle.pendown()
turtle.pensize(25)
turtle.pencolor("purple")
drawSnake(40,80,4)
turtle.done()

绘制螺旋线

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import turtle
def drawHelix(w, h, size, padding):
turtle.setup(w+50 , h+50, None, None)
turtle.pensize(size)
turtle.penup()
turtle.fd(-0.5*w)
turtle.seth(-90)
turtle.fd(0.5*h)
turtle.pendown()
while h>0:
h-=padding
turtle.seth(90)
turtle.fd(h)
w-=padding
turtle.seth(0)
turtle.fd(w)
h-=padding
turtle.seth(-90)
turtle.fd(h)
w-=padding
turtle.seth(180)
turtle.fd(w)
drawHelix(200, 200, 5, 8)
turtle.done()

更简单的方法

1
2
3
4
5
6
import turtle
t = turtle.Pen()
for x in range(0, 200, 10):
t.forward(x)
t.left(90)
turtle.done()

数字类型

整型


Python语言能够支持无限制且准确的整数计算,因此,如果希望获得精度更高的计算结果,往往采用整数而不直接采用浮点数。

浮点型

1
2
import sys
print(sys.float_info)
1
2
3
4
5
import decimal
a = decimal.Decimal('3.1415926')
b = decimal.Decimal('1.2345678')
decimal.getcontext().prec = 25
print(a*b)

复数

1
2
3
complex = 6e-19 + 8j
print("实部: {:}".format(complex.real))
print("虚部: {:}".format(complex.imag))

复数类型中实数部分和虚数部分的数值都是浮点类型。

数字类型的操作

9个基本数值运算操作符:

1
print(abs(3-4j)) # 5.0

1
print(complex(4.3,1.2)) # (4.3+1.2j)

math 库




字符串

1
2
3
4
print('''云想"衣裳"花想'容',
春风扶栏露华浓.
若非群玉山头见,
会向瑶台月下逢.''')

pyhton不区分字符和字符串, 都是字符串类型

基本字符串操作符

内置字符串处理函数

内置字符串处理方法

字符串的格式化

format()

1
2
3
4
5
6
print("{0}{0}{0}{1}{2}".format('w','.slacr','.site'))
print("{0:->20,.4f}".format(1234.56789))
# 使用-填充, 右对齐, 宽度20, 有分隔符, 精度4, float
print("{0:b}, {0:c}, {0:d}, {0:o}, {0:x}".format(425))
print("{0:.2e}, {0:.2f}, {0:.2%}".format(1.23))
print("{:>15s}".format("test"))

文字进度条显示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# prac textProgressBar
import time
time.time()
scale = 50
print("execute starts".center(scale//2, '-'))
st = time.time()
for i in range(scale + 1):
a = '*' * i
b = '.' * (scale - i)
c = (i/scale) * 100
t = time.time() - st
print("\r{:^3.0f}%[{}->{}]{:.2f}s".format(c, a, b, t), end=" ")
time.sleep(0.05)
print("\n"+"execute ends".center(scale//2, '-'))

程序的控制结构

1
2
3
4
5
for ch in "人生得意须尽欢":
print("循环中: " + ch)
else:
print("循环正常结束")
# for/while循环保留字else的扩展方式, 只有循环正常结束才会执行

random 库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# -*- coding: utf-8 -*-

import random
print(random.random())
print(random.uniform(1,2))
print(random.randrange(0,10,2))
print(random.choice(range(10)))
ls = list(range(10))
print(ls)
random.shuffle(ls)
print(ls)

random.seed(33)
print("{}".format(random.randint(1, 10)))

'''
0.5703284231368732
1.6322329955787787
4
7
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 3, 7, 6, 4, 5, 2, 9, 8]
10
'''

蒙特卡洛方法计算圆周率

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# -*- coding: utf-8 -*-

# 蒙特卡洛方法计算圆周率
from random import random
from math import sqrt
from time import perf_counter
DARTS = 10000
HITS = 0;
start = perf_counter()
for i in range(1, DARTS+1):
x, y = random(), random()
dist = sqrt(x**2 + y**2)
if dist <= 1.0:
HITS += 1
PI = 4 * (HITS / DARTS)
print("圆周率PI的值: {}".format(PI))
print("运行时间: {:5.5f}s".format(perf_counter() - start))

'''
圆周率PI的值: 3.128
运行时间: 0.00458s
'''

异常处理

1
2
3
4
5
6
7
8
9
10
# try- except 
try:
alp = "ABCDE"
idx = eval(input("请输入一个[0, 4]整数:"))
print(alp[idx])
except NameError:
print("输入必须为可被eval()识别的整数")
except:
# 其他异常
print("其他错误")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# try- except - else - finally
try:
alp = "ABCDE"
idx = eval(input("请输入一个[0, 4]整数:"))
print(alp[idx])
except NameError:
print("输入必须为可被eval()识别的整数")
except IndexError:
print("输入的下标越界")
except:
print("其他错误")
else:
# 当没有发生异常, 执行保留字else中的语句
print("无异常")
finally:
# 无论 try 块中有无异常发生, 都将执行
print("程序执行完毕")

函数和代码复用

lambda 函数

1
2
3
4
5
6
7
# -*- coding: utf-8 -*-

def sum_1(x, y):
return x + y
sum_2 = lambda x, y : x+y
print(sum_1(1, 2))
print(sum_2(1, 2))

可选参数 和 可变参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# -*- coding: utf-8 -*-

def increase(x, add=1):
return x+add
# add 为默认参数/ 可选参数, 必须放参数表末尾
print(increase(1, 3))
print(increase(1))

def getSum(x, *ls):
print(type(ls))
for i in ls:
x+=i
return x
# ls 为可变参数, 类型为元组
print(getSum(1, 2, 3))
print(getSum(1, 5))

'''
4
2
<class 'tuple'>
6
<class 'tuple'>
6
'''

参数的位置和名称传递

Python提供了按照形参名称输入实参的方式, (发现一些内置函数并不支持)
这样传递的参数叫关键字参数(keyword arguments)
有些内置函数是不采纳关键字参数的, 比如, print(math.log(4, base=2)),
会报错TypeError: log() takes no keyword arguments, 自定义函数都是支持的.

1
2
3
4
import math
def getDist(x, y):
return math.sqrt(x**2 + y**2)
print(getDist(x=1, y = 2))

全局变量 局部变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# -*- coding: utf-8 -*-

x = 0
def add(x):
x+=10
add(x)
print(x) # 0

y = 0
def add2(z):
global y # 声明 y 全局为全局作用域的y
y+=z
add2(100)
print(y) # 100

ls = []
def func(a):
ls.append(a)
func("test")
# 列表类型不需要global声明全局, 在调用时如若内层没有, 会自动绑定外层
# 对于列表类型,函数可以直接使用全局列表而不需要采用global进行声明
'''
个人觉得这跟python 的弱类型有关, 强类型语言比如C\java, 变量的声明和变量初始化是可区分的
比如 `int a; a = 1`; 而 py 没有类型限定, 可以直接 a = 1, 导致无法在一个作用域内判断是
在这个作用域内声明还是在这个作用域内为变量赋值. 从结果看, python中在一个作用域内声明
一个同名变量是会被理解成局部变量的, 也就是声明新变量而不是赋值, 不会优先向外层查找.
'''
print(ls)

(1)简单数据类型变量无论是否与全局变量重名,仅在函数内部创建和使用,
函数退出后变量被释放,如有全局同名变量,其值不变。
(2)简单数据类型变量在用global保留字声明后,作为全局变量使用,函数退
出后该变量保留且值被函数改变。
(3)对于组合数据类型的全局变量,如果在函数内部没有被真实创建的同名变
量,则函数内部可以直接使用并修改全局变量的值。
(4)如果函数内部真实创建了组合数据类型变量,无论是否有同名全局变量,
函数仅对局部变量进行操作,函数退出后局部变量被释放,全局变量值不变。

datetime 库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# -*- coding: utf-8 -*-


from datetime import datetime

today = datetime.now()
# 获取当前日期和时间, 返回datetime类型对象
print(today)

utcToday = datetime.utcnow()
# 获取utc 世界标准时间, Greenwich 天文台位置为本初子午线
print(utcToday)

sd = datetime(2003, 10, 24, 10, 9, 8, 7)
# 构造datetime类的对象
print(sd)
print(sd.microsecond)
print(sd.max)

print(sd.isoformat())
# iso 8601 标准时间
print(sd.isoweekday())
print(sd.strftime("%Y * %B * %d ==== %a, %H, %p, %M"))

七位数码管动态显示时间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# -*- coding: utf-8 -*-

import turtle
import datetime
import time

# 七位数码管动态显示时间

# 绘制单段数码管
def drawLine(draw):
drawGap()
turtle.pendown() if draw else turtle.penup()
turtle.fd(40)
drawGap()
turtle.right(90)

# 绘制数码管间隔
def drawGap() :
turtle.penup()
turtle.fd(5)

# 根据数字绘制七位数码管
def drawDigit(d):
drawLine(True) if d in [2, 3, 4, 5, 6, 8, 9, '-'] else drawLine(False)
drawLine(True) if d in [0, 1, 3, 4, 5, 6, 7, 8, 9] else drawLine(False)
drawLine(True) if d in [0, 2, 3, 5, 6, 8, 9] else drawLine(False)
drawLine(True) if d in [0, 2, 6, 8] else drawLine(False)
turtle.left(90)
drawLine(True) if d in [0, 4, 5, 6, 8, 9] else drawLine(False)
drawLine(True) if d in [0, 2, 3, 5, 6, 7, 8, 9] else drawLine(False)
drawLine(True) if d in [0, 1, 2, 3, 4, 7, 8, 9] else drawLine(False)
turtle.penup()
turtle.seth(0)
turtle.fd(20)

# 绘制整个时间
def drawDate(date):
turtle.pencolor(0, 0, 0)
for i in date:
drawDigit(i) if i == '-' else drawDigit(eval(i))

# 主函数
def main():
turtle.setup(800, 350, 200, 200)
turtle.hideturtle()
turtle.tracer(0)
turtle.penup()
turtle.pensize(5)

while True:
turtle.clear()
turtle.home()
turtle.fd(-350)
drawDate(datetime.datetime.now().strftime("%H-%M-%S"))
turtle.update() # 更新画布
time.sleep(1)
turtle.done()

main()

函数的递归

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# -*- coding: utf-8 -*-

import sys
sys.setrecursionlimit(2000)
print(sys.getrecursionlimit())

def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n-1)
print(factorial(5))

# 翻转字符串
def reverse(str):
if str == "":
return str
else:
return str[1:] + str[0]

print(reverse("文征明"))

print("祝枝山"[::-1])

s = "123"
print("".join([s[-(i+1)] for i, c in enumerate(s)]))

1
2
3
4
5
6
7
def nest_GCD(a, b):
if not b:
return a
r = a % b
return nest_GCD(b, r)

print(nest_GCD(108, 162))

科赫曲线绘制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# -*- coding: utf-8 -*-

import turtle
def koch(size, n):
if n == 0:
turtle.fd(size)
else:
for angle in [0, 60, -120, 60]:
turtle.left(angle)
koch(size/3, n-1)

def main():
turtle.setup(800, 400)
turtle.speed(2)
turtle.penup()
turtle.hideturtle()
turtle.goto(-300, -50)
turtle.pendown()
turtle.pensize(2)
koch(600, 3)

main()

汉诺塔

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# -*- coding: utf-8 -*-

# hanoi
times = 0

def hanoi(a, c, b, n):
if n==1:
global times # 全局变量如果只使用其值而不改变其值则无需 global, 只有需要改变值的情况才需要 global 声明
times+=1
print("第" + str(times) + "次: " + a + " ==> " + c)

else:
hanoi(a, b, c, n-1)
hanoi(a, c, b, 1)
hanoi(b, c, a, n-1)

hanoi('A', 'C', 'B', 3)

组合数据类型

tuple

1
2
3
4
5
6
7
8
9
10
# -*- coding: utf-8 -*-

pos = (1, 2, 3)
coords = ("S", "N", ("W", "E"))

print(coords[2][1])

import math
for x, y in ((1, 0), (2, 3), (5, 5)):
print(math.hypot(x, y))

set

集合中的元素不可重复,元素类型只能是固定数据类型,例如整数、浮点数、字符串、元组等,列表、字典和集合类型本身都是可变数据类型,不能作为集合的元素出现。Python编译器中界定固定数据类型与否主要考察类型是否能够进行哈希运算。能够进行哈希运算的类型都可以作为集合元素。



1
2
3
4
5
6
7
8
9
10
11
12
13
14
# -*- coding: utf-8 -*-

group = {"zhang", "wang", "liu", ("zhi", "hui"), 2, 3, 5,9}
print(group)

if "zhang" in group:
print("yes")

group2 = {"zhao", "qian", "sun", "li"}
group |= group2
print(group)

group -= {"liu"}
print(group)

列表类型和操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# -*- coding: utf-8 -*-

ls = [1, 2, "test"]
del ls[-1]
print(ls)
ls *= 3
print(ls)
ls.remove(1) # 只移除第一个
print(ls)
ls.append(3)
print(ls)
i = ls.pop(-1)
print(i)

ls[1 : -1] = ["good"]
print(ls)

ls = [3, 4, 5, 1, 2]
ls = sorted(ls)
print(ls)
ls.sort(reverse = True)
print(ls)
ls.reverse()
print(ls)

基本统计值计算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# -*- coding: utf-8 -*-

# 基本统计值计算

import math


# 获取输入
def getNums():
nls = []
n = input("请输入数字, 直接按回车键退出:")
while n != "":
nls.append(eval(n))
n = input("请输入数字, 直接按回车键退出:")
return nls

# 计算平均数
def avg(nls):
return sum(nls)/len(nls)

# 计算方差
def dev(nls):
m = avg(nls)
s = 0.0
for i in nls:
s += ((i-m)**2)
return math.sqrt(s/(len(nls)-1))

# 计算中位数
def med(nls):
s_nls = sorted(nls)
l_nls = len(nls)
if l_nls % 2 == 0:
return 0.5 * (s_nls[l_nls//2] + s_nls[l_nls//2 + 1])
else:
return s_nls[l_nls//2]
# 主函数
def main():
nls = getNums()
print("计算结果: ")
print("平均值:\t{}".format(avg(nls)))
print("中位数:\t{}".format(med(nls)))
print("方差:\t{:.2f}".format(dev(nls)))
main()

字典类型和操作

Python语言中,字符串、列表、元组等都采用数字索引,字典采用字符索引。

1
2
3
4
5
6
7
8
# -*- coding: utf-8 -*-
dic = {"up":(0, 1), "down":(0, -1), "right":(1, 0), "left":(-1, 0)}
for i in dic:
print(dic[i])

print(dic.items())
print(dic.pop("up"))
print(list(dic.keys()))

jieba 库

一个重要的第三方中文分词函数库

1
2
3
4
5
6
7
8
9
# -*- coding: utf-8 -*-

import jieba

print(jieba.lcut("大庇天下寒士俱欢颜"))
print(jieba.lcut("大庇天下寒士俱欢颜", True)) # 全模式, 冗余度更高
print(jieba.lcut_for_search("被夏天的镰刀割去, 麦子他能说个啥"))
jieba.add_word("说个啥")
print(jieba.lcut_for_search("被自家的驴啃了, 麦子他又能说个啥"))

文本词频统计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# -*- coding: utf-8 -*-

import jieba

# 红楼梦 词频 分析
txt = open("红楼梦.txt", "r", encoding="utf-8").read()
words = jieba.lcut(txt)
counts = {}
for word in words:
if len(word) == 1: # 排除单个分词
continue
else:
counts[word] = counts.get(word, 0) + 1
items = list(counts.items())
items.sort(key=lambda x: x[1], reverse=True)
for i in range(50):
word, cnt = items[i]
print("{:<10}{:>5}".format(word, cnt))

文件和数据格式化

1
2
3
4
5
6
7
8
9
# 文件操作
try:
text = open("红楼梦.txt", "rt", encoding = "utf-8")
except FileNotFound:
print("无此文件")
res = text.readlines(10)
for line in res:
print(line)
text.close()

1
2
3
4
5
6
7
8
9
10
11
12
13
# -*- coding: utf-8 -*-

# 写入文件
f = open("test.txt","a+t")
ls = []
s = input("请输入文字, 按回车退出:\n->: ")
while s != "":
ls.append(s)
ls.append("\n")
s = input("->: ")

f.writelines(ls)
f.close()

PIL(Python Image Library) 库

PIL库是一个具有强大图像处理能力的第三方库,不仅包含了丰富的像素、色彩操作功能,还可以用于图像归档和批量处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# -*- coding: utf-8 -*-

from PIL import Image
from PIL import ImageFilter

pic = Image.open("pic1.jpg")
pic_af = pic.filter(ImageFilter.CONTOUR())

pic_af.save("pic1_af.jpg")

from PIL import ImageEnhance
pic_af2 = ImageEnhance.Contrast(pic_af)
pic_af2.enhance(0.5).save("pic1_af2.jpg")


pic_af3 = ImageEnhance.Sharpness(pic_af2.enhance(0.5))
pic_af3.enhance(10).save("pic1_af3.jpg")

图像的字符画绘制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# -*- coding: utf-8 -*-

from PIL import Image

# 字符集, 对应灰度递减
ascii_char =list('"$?WM#*oahkbdpqwmZO0QLCJUYXzcvunxr\
jft/\()1()[]?-/+0<>i!;:,\^`.')

def get_char(r, b, g, alpha = 256):
if alpha == 0:
return " "
gray = int(0.2126 * r + 0.7152 * g + 0.0072 * b) # rgb 转 灰度
unit = 256 / len(ascii_char) # 单位字符的灰度
return ascii_char[int(gray//unit)] # 根据灰度确定对应字符

def main():
im = Image.open("kun.jpeg")
WIDTH, HEIGHT = 90, 30
im = im.resize((WIDTH, HEIGHT))
txt = ""
for i in range(HEIGHT):
for j in range(WIDTH):
txt += get_char(*im.getpixel((j,i)))
txt += "\n"
fo = open("kun_char.txt", "w")
fo.write(txt)
fo.close()

main()

csv

逗号分隔数值的存储格式叫做CSV格式(Comma-Separated Values,逗号分隔值),它是一种通用的、相对简单的文件格式,在商业和科学上广泛应用,尤其应用在程序之间转移表格数据。该格式的应用有如下一些基本规则。
(1)纯文本格式,通过单一编码表示字符。
(2)以行为单位,开头不留空行,行之间没有空行。
(3)每行表示一个一维数据,多行表示二维数据。
(4)以逗号(英文,半角)分隔每列数据,列数据为空也要保留逗号。
(5)对于表格数据,可以包含或不包含列名,包含时列名放置在文件第一行。

Python提供了一个读写csv的标准库,可以通过import csv使用。

1
2
3
4
5
6
7
8
9
10
11
# -*- coding: utf-8 -*-

data = '''姓名,年龄,职业
张三,29,农民工
李四,34,教师
王五,99,程序员
'''

fp = open("名单表.csv", "w")
fp.writelines(data)
fp.close()

csv 数据在python中可以使用二维列表表示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# csv 转 二维列表
fo = open("名单表.csv", "r")
ls = []
for line in fo:
line = line.replace("\n", "")
ls.append(line.split(","))
print(ls)
fo.close()

txt = "1&2&3&"
ltxt = txt.split('&')
print(ltxt)

# 列表转 csv 格式
ls1 = ["q", "w", "e", "r"]
print(",".join(ls1))

csv 转 html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# -*- coding: utf-8 -*-

# csv 转 HTML

seg = '''
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>

<body>

<table>
<caption>名单表</caption>
<tr>
<th>(0,0)</th>
<th>(0,1)</th>
<th>(0,2)</th>
</tr>
<tr>
<td>(1,0)</td>
<td>(1,1)</td>
<td>(1,2)</td>
</tr>
<tr>
<td>(2,0)</td>
<td>(2,1)</td>
<td>(2,2)</td>
</tr>
<tr>
<td>(3,0)</td>
<td>(3,1)</td>
<td>(3,2)</td>
</tr>
</table>
</body>

</html>
'''

nl = open("名单表.csv", "r",)
ls = []
for l in nl:
l = l.replace("\n", "")
ls.append(l.split(","))
nl.close()

print(ls)
for i in range(len(ls)):
for j in range(len(ls[i])):
seg = seg.replace("({0:},{1:})".format(i, j), ls[i][j])

nf = open("名单表.html", "w", encoding =( "utf-8"))
nf.writelines(seg)
nf.close()

# 有点多余

json 库

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式
当多个键值对放在一起时,JSON有如下一些约定。
(1)数据保存在键值对中。
(2)键值对之间由逗号分隔。
(3)大括号用于保存键值对数据组成的对象。
(4)方括号用于保存键值对数据组成的数组。

json库是处理JSON格式的Python标准库

json库主要包括两类函数:操作类函数和解析类函数。操作类函数主要完成外部JSON格式和程序内部数据类型之间的转换功能;解析类函数主要用于解析键值对内容。
一般来说,JSON格式的对象将被json库解析为字典,JSON格式的数组将被解析为列表。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# -*- coding: utf-8 -*-

import json
dt = {"e": 10, "b": 7, "c": 12, "d": 4 }
s1 = json.dumps(dt)
s2 = json.dumps(dt, sort_keys=True, indent = 4)

print(s1)
print(s2)

d1 = json.loads(s1)
print(s1)

'''
{"e": 10, "b": 7, "c": 12, "d": 4}
{
"b": 7,
"c": 12,
"d": 4,
"e": 10
}
{"e": 10, "b": 7, "c": 12, "d": 4}
'''
csv 转 json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# -*- coding: utf-8 -*-

import json

# csv 转 json
fp = open("名单表.csv", "r")
ls = []
for line in fp:
line = line.replace("\n", "")
ls.append(line.split(","))
fp.close()

# print(ls)

fp2 = open("名单表.json", "w")
for i in range(1, len(ls)):
ls[i] = dict(zip(ls[0], ls[i]))

json.dump(ls[1:], fp2, sort_keys=True, indent=4, ensure_ascii=False)
fp2.close()

pyinstaller

pyinstaller是一个十分有用的第三方库,它能够在Windows、Linux、Mac OS X等操作系统下将Python源文件打包,通过对源文件打包,Python程序可以在没有安装Python的环境中运行,也可以作为一个独立文件方便传递和管理。

计算生态和模块编程

Python官方网站提供了第三方库索引功能(the Python Package Index,PyPI)
https://pypi.python.org/pypi
在计算生态思想指导下,编写程序的起点不再是探究每个具体算法的逻辑功能和设计,而是尽可能利用第三方库进行代码复用,探究运用库的系统方法。这种像搭积木一样的编程方式,称为“模块编程”。每个模块可能是标准库、第三方库、用户编写的其他程序或对程序运行有帮助的资源等。模块编程与模块化设计不同,模块化设计主张采用自顶向下设计思想,主要开展耦合度低的单一程序设计与开发,而模块编程主张利用开源代码和第三方库作为程序的部分或全部模块,像搭积木一样编写程序。

批量安装

1
2
3
4
5
6
7
8
9
10
11
12
13
# -*- coding: utf-8 -*-

import os
libs = {"numpy", "PyQt5", "pygame"}

try:
for lib in libs:
os.system("pip install " + lib)
# 调用控制台
print("Done!")
except:
print("Falied Somehow")

科学计算和可视化

numpy 库

Python标准库中提供了一个array类型,用于保存数组类型数据,然而这个类型不支持多维数据,处理函数也不够丰富,不适合数值运算。因此,Python语言的第三方库numpy得到了迅速发展,至今,numpy已经成为了科学计算事实上的标准库。
numpy库处理的最基础数据类型是由同种元素构成的多维数组(ndarray),简称“数组”。数组中所有元素的类型必须相同,数组中元素可以用整数索引,序号从0开始。ndarray类型的维度(dimensions)叫做轴(axes),轴的个数叫做秩(rank)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# -*- coding: utf-8 -*-

import numpy as np
# as 保留字改变后序代码中库的命名空间

ls = [1, 2, 3]
print(ls)
m1 = np.array(ls, int)
print(m1)

m2 = np.arange(1, 10, 2)
print(m2)

m3 = np.linspace(10, 100, 5)
print(m3)

m4 = np.random.rand(3, 4)
print(m4)

m5 = np.ones((2, 3), dtype=int)
print(m5)


m6 = np.empty((4, 3), dtype=int)
print(m6)


print("矩阵的秩:\t" + str(m6.ndim))
print("矩阵的行列数:\t" + str(m6.shape))
print("矩阵元素总个数:\t" + str(m6.size))
print("矩阵元素类型:\t" + str(m6.dtype))
print("矩阵每个元素字节大小:\t" + str(m6.itemsize))
print("包含实际数组的缓冲区地址:\t" + str(m6.data))
print("数组元素的迭代器:\t" + str(m6.flat))

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# -*- coding: utf-8 -*-

import numpy as np

m = np.ones((3, 4))
print(m)

for i in range(len(m)):
for j in range(len(m[i])):
m[i][j] = i*2 + j
print(m)


m1 = m.reshape(1, 12)
print(m1)

m.resize((4, 3))
print(m)


m2 = m.swapaxes(0, 1)
# 交换 1d 和 2d, 相当于转秩
print(m2)

m3 = m.flatten()
print(m3)
# 降维 reshape 和 resize 也能做

m4 = m.ravel()
# 作用同flatten, 返回数组的一个视图
print(m4)

print(m)
print(m[1:3])

图像的手绘效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from PIL import Image
import numpy as np

# 读取图像
im = np.array(Image.open("./c.jpg").convert("L"))

# 反变换
im1 = 255-im

# 区间变换
im2 = (100/255) * im + 150

# 像素平方处理
im3 = 255*(im/255)**2

# 将处理后的图像保存到文件
pil_im1 = Image.fromarray(np.uint(im1)).convert("RGB")
pil_im2 = Image.fromarray(np.uint(im2)).convert("RGB")
pil_im3 = Image.fromarray(np.uint(im3)).convert("RGB")

pil_im1.save("im1.jpg")
pil_im2.save("im2.jpg")
pil_im3.save("im3.jpg")

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

# 图像手绘效果
from PIL import Image
import numpy as np

vec_el = np.pi/2.2 # 光源的俯视角度, 弧度值
vec_az = np.pi/4 # 光源的方位角度, 弧度值
# 方向角和俯仰角的概念:
# 方向角相当于经线, 以正北为0, 顺时针3 60
# 俯仰角相当于纬线, 水平为0, 上下90
depth = 10
im = Image.open('c.jpg').convert("L")
a = np.asarray(im).astype('float')
grad = np.gradient(a) # 图像灰度的梯度值, 返回一个x, y方向梯度值的二元组
grad_x, grad_y = grad
grad_x = grad_x * depth/100
grad_y = grad_y * depth/100
dx = np.cos(vec_el)*np.cos(vec_az)
dy = np.cos(vec_el)*np.sin(vec_az)
dz = np.sin(vec_el)
A = np.sqrt(grad_x**2 + grad_y**2 + 1. )
uni_x = grad_x/A
uni_y = grad_y/A
uni_z = 1./A
a2 = 255*(dx*uni_x + dy*uni_y + dz*uni_z) # 光源归一化
a2 = a2.clip(0, 255)
im2 = Image.fromarray(a2.astype('uint8')) # 重构图像
im2.save('c_hr.jpg')

matplotlib

matplotlib.pyplot库

matplotlib.pyplot是matplotlib的子库.plt子库提供了一批操作和绘图函数,每个函数代表对图像进行的一个操作,比如创建绘图区域、添加标注或者修改坐标轴等

1
2
3
4
5
6
import matplotlib.pyplot as plt
plt.figure(figsize=(8, 4))
plt.subplot(321)

plt.axes([0.1, 0.1, 0.5, 0.3], facecolor="y")
plt.show()

1
2
3
4
5
6
7
8
# -*- coding: utf-8 -*-

import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 6, 100)
y = np.cos(2*np.pi*x) * np.exp(-x) + 0.8
plt.plot(x, y, 'k', color='r', linewidth=3, linestyle='-')
plt.show()

1
2
3
4
5
6
7
8
9
10
11
# -*- coding: utf-8 -*-

import numpy as np
import matplotlib.pyplot as plt

plt.plot([1, 2, 4], [1, 2, 3])
print(plt.axis()) # (0.85, 4.15, 0.9, 3.1)
plt.text(3, 7, 'test')
plt.axis([0, 5, 0, 8])
plt.grid('on')
plt.show()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# -*- coding: utf-8 -*-

import numpy as np
import matplotlib.pyplot as plt
import matplotlib

matplotlib.rcParams['font.family'] = 'SimHei'
# "runtime configuration parameters"
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
plt.plot([1, 2, 4], [1, 2, 3])
plt.title('坐标系标题')
plt.xlabel('时间/s')
plt.ylabel('范围/m')
plt.xticks([1, 2, 3, 4, 5], [r' \pi/3 ', r' 2\pi/3 ', r' \pi ', \
r' 3\pi/4 ', r' 5\pi/3 '])
plt.show()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# -*- coding: utf-8 -*-

import numpy as np
import matplotlib.pyplot as plt
import matplotlib

x = np.linspace(0, 10, 1000)
y = np.cos(2*np.pi*x) * np.exp(-x) + 0.8
plt.plot(x, y, 'ko', color = 'r', label = ' exp-dacay ', linewidth = 3)
# 'ko'-fmt 格式字符串, 黑色圆点 , color = "r" 会覆盖, 常见
'''
'b':蓝色(blue)
'g':绿色(green)
'r':红色(red)
'c':青色(cyan)
'm':品红色(magenta)
'y':黄色(yellow)
'k':黑色(black)
'w':白色(white)
'''
plt.axis([0, 6, 0, 1.8])
ix = (x>0.8) & (x<3)
plt.fill_between(x, y, 0, where = ix, facecolor='gray', alpha=1)
plt.text(0.5*(0.8+3), 0.2, r" \int_a^b f(x) \mathrm{d}x ", horizontalalignment = 'center')
plt.legend()
plt.show()

阻尼衰减曲线坐标图绘制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# -*- coding: utf-8 -*-

import numpy as np
import matplotlib.pyplot as plt
import matplotlib

matplotlib.rcParams['font.family'] = 'SimHei'
matplotlib.rcParams['font.sans-serif'] = ['SimHei']

# 绘制图像与注释
def Draw(pcolor, nt_point, nt_text, nt_size):
plt.plot(x, y, 'k', label = " exp_decay ", color=pcolor, \
linewidth=3, linestyle='-')
plt.plot(x, z, 'b--', label = " cos(x^2) ", linewidth=1)
plt.xlabel('时间/s')
plt.ylabel('幅度/mV')
plt.title('阻尼衰减曲线绘制')
plt.annotate(r' \cos(2\pi t)\exp(-t) ', xy = nt_point, xytext=nt_text, \
fontsize=nt_size, arrowprops=dict(arrowstyle='->', \
connectionstyle='arc3, rad=.1'))
# 绘制阴影部分
def Shadow(a, b):
ix = (x>a) & (x<b)
plt.fill_between(x, y, 0, where=ix, facecolor='grey', alpha=0.5)
plt.text(0.5*(a+b), 0.2, r" \int_a^b f(x) \mathrm{d}x ", \
horizontalalignment='center')

# 设置坐标轴
def XY_Axis(x_start, x_end, y_start, y_end):
plt.xlim(x_start, x_end)
plt.ylim(y_start, y_end)
plt.xticks([np.pi/3, 2*np.pi/3, 1*np.pi, 4*np.pi/3, 5*np.pi/3], \
[r' \pi/3 ',r' 2\pi/3 ',r' \pi ', r' 4\pi/3 ', r' 5\pi/3 ' ])

x = np.linspace(0.0, 6.0, 100)
y = np.cos(2*np.pi*x) * np.exp(-x) + 0.8
z = 0.5 * np.cos(x**2) + 0.8
note_point, note_text, note_size = (1, np.cos(2*np.pi)*np.exp(-1)+0.8), \
(1, 1.4), 14
fig = plt.figure(figsize=(8,6), facecolor='white')
plt.subplot(111)
Draw("red", note_point, note_text, note_size)
XY_Axis(0, 5, 0, 1.8)
Shadow(0.8, 3)
plt.legend()
plt.savefig('sample.jpg')
plt.show()

多级雷达图绘制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# -*- coding: utf-8 -*-

import numpy as np
import matplotlib.pyplot as plt
import matplotlib

matplotlib.rcParams['font.family'] = 'SimHei'
matplotlib.rcParams['font.sans-serif'] = ['SimHei']

labels = np.array(['综合', 'KDA', '发育', '推进', '生存', '输出'])
nAttr = 6
data = np.array([7, 4, 5, 6, 9, 2]) # 数据值
angles = np.linspace(0, 2*np.pi, nAttr, endpoint=False)
print(angles)
data = np.concatenate((data, [data[0]]))
angles = np.concatenate((angles, [angles[0]]))
fig = plt.figure(facecolor="white")
ax = plt.subplot(111, polar=True)
# 设置圈刻度线的样式为虚线
ax.xaxis.grid(linestyle='dashed')
ax.yaxis.grid(linestyle='dashed')
# 极坐标
plt.plot(angles, data, 'bo-', color='g', linewidth=2)
plt.fill(angles, data, facecolor='g', alpha=0.25)
plt.thetagrids(angles[:-1]*180/np.pi, labels)
plt.figtext(0.52, 0.95, 'DOTA能力值雷达图', ha='center')
plt.grid(True)
plt.savefig('data_radar.jpg')
plt.show()

HollandRadar 绘制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# -*- coding: utf-8 -*-

import numpy as np
import matplotlib.pyplot as plt
import matplotlib

matplotlib.rcParams['font.family'] = 'SimHei'
matplotlib.rcParams['font.sans-serif'] = ['SimHei']

radar_labels = np.array(['研究型(I)', '艺术型(A)', '社会型(S)', \
'企业型(E)', '常规型(C)', '现实型(R)'])
nAttr = len(radar_labels)
data = np.array([
[0.40, 0.32, 0.35, 0.30, 0.30, 0.88],
[0.85, 0.35, 0.30, 0.40, 0.40, 0.30],
[0.43, 0.89, 0.30, 0.28, 0.22, 0.30],
[0.30, 0.25, 0.48, 0.85, 0.45, 0.40],
[0.20, 0.38, 0.87, 0.45, 0.32, 0.28],
[0.34, 0.31, 0.38, 0.40, 0.92, 0.28]
]) # 数据值

data_labels = ('工程师', '实验员', '艺术家', '推销员', '社会工作者', '记事员')
angles = np.linspace(0, 2*np.pi, nAttr, endpoint=False)
angles = np.concatenate((angles, [angles[0]]))
data = np.concatenate((data, [data[0]]))
fig = plt.figure(figsize=(8, 4),facecolor="white")
plt.subplot(111, polar=True)

plt.plot(angles, data, 'o-', linewidth=1.5, alpha=0.2)
plt.fill(angles, data, alpha=0.25)
plt.thetagrids(angles[:-1]*180/np.pi, radar_labels)
plt.figtext(0.52, 0.95, 'Holland Charcter Analysis', ha='center', size=20)
legend = plt.legend(data_labels, loc=(0.94, 0.80), labelspacing=0.1)
plt.setp(legend.get_texts(), fontsize='small')
plt.grid(True)
plt.savefig('holland_radar.jpg')
plt.show()

网络爬虫和自动化

Robots排除协议

Robots排除协议(Robots Exclusion Protocol),也被称为爬虫协议,它是网站管理者表达是否希望爬虫自动获取网络信息意愿的方法。管理者可以在网站根目录放置一个robots.txt文件,并在文件中列出哪些链接不允许爬虫爬取。一般搜索引擎的爬虫会首先捕获这个文件,并根据文件要求爬取网站内容。Robots排除协
议重点约定不希望爬虫获取的内容,如果没有该文件则表示网站内容可以被爬虫获得,然而,Robots协议不是命令和强制手段,只是国际互联网的一种通用道德规范。绝大部分成熟的搜索引擎爬虫都会遵循这个协议,建议个人也能按照互联网规范要求合理使用爬虫技术。

request 库

requests库是一个简洁且简单的处理HTTP请求的第三方库,它的最大优点是程序编写过程更接近正常URL访问过程。这个库建立在Python语言的urllib3库的基础上,类似这种在其他函数库之上再封装功能、提供更友好函数的方式在Python语言中十分常见。在Python生态圈里,任何人都有通过技术创新或体验创新发表意见和展示才华的机会。requests库支持非常丰富的链接访问功能,包括国际域名和URL获取、HTTP长连接和连接缓存、HTTP会话和Cookie保持、浏览器使用风格的SSL验证、基本的摘要认证、有效的键值对Cookie记录、自动解压缩、自动内容解码、文件分块上传、HTTP(S)代理功能、连接超时处理、流数据下载等。有关requests库的更多介绍请访问http://docs.python-requests.org

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# -*- coding: utf-8 -*-

import requests

# 获取网页内容
def getHTMLText(url):
try:
r = requests.get(url, timeout = 30)
r.raise_for_status() # 状态码非200, 引发异常
r.encoding = 'utf-8'
return r.text
except:
return "error"

url = "http://www.baidu.com"
print(getHTMLText(url))

beautifulsoup4 库

使用requests库获取HTML页面并将其转换成字符串后,需要进一步解析HTML页面格式,提取有用信息,这需要处理HTML和XML的函数库。beautifulsoup4库,也称为Beautiful Soup库或bs4库,用于解析和处理HTML和XML。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# -*- coding: utf-8 -*-

import requests
from bs4 import BeautifulSoup

# 获取网页内容
def getHTMLText(url):
try:
r = requests.get(url, timeout = 30)
r.raise_for_status() # 状态码非200, 引发异常
r.encoding = 'utf-8'
return r.text
except:
return "error"

url = "http://www.baidu.com"

soup = BeautifulSoup(getHTMLText(url), features="lxml")
print(type(soup))
title = soup.title
print(type(title))
print(title)
head = soup.head
print(head.contents[0].name)
print(soup.p.a.string)

# BeautifulSoup.find(name, attrs, recursive, string) 返回第一个
# BeautifulSoup.find_all(name, attrs, recursive, string, limit)
na = soup.find_all('a')
print(na)

script = soup.find_all('script')
print(script)

import re
baidu = soup.find_all(string = re.compile("百度"))
print(baidu)

jq = soup.find_all('script', {'src' : re.compile("jquery")})

中国大学排名爬虫

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# -*- coding: utf-8 -*-

import requests
from bs4 import BeautifulSoup

allUniv = []
def getHTMLText(url):
try:
r = requests.get(url, timeout=30)
r.raise_for_status()
r.encoding = 'utf-8'
return r.text
except:
return "error"

def fillUnivList(soup):
data = soup.find_all('tr')
# print(data)
for tr in data:
ltd = tr.find_all('td')
if len(ltd) == 0:
continue
singleUniv = []
for td in ltd:
a = td.find('a', {'class' : "name-cn"})
if a == None:
singleUniv.append(td.text.strip())
else:
singleUniv.append(a.text.strip())
allUniv.append(singleUniv)
'''
.string方法用于获取一个元素的直接子节点的文本内容。它适用于那些只包含一
个直接文本节点的元素。如果元素包含多个子节点,或者子节点包含注释或其他非
字符串类型的节点,则.string方法返回None。

.text方法用于获取一个元素及其所有子节点的文本内容。它会将所有子节点的文本
内容连接起来,并返回一个完整的文本字符串。
'''

def printUnivList(num):
print("{:<8}{:<15}{:<10}{:<5}{:<7}{:<7}".format("排名", "名称", "省市", "类型", "总分", "办学层次"))
for i in range(num):
u = allUniv[i]
print("{:<8}{:<15}{:<10}{:<5}{:<7}{:<7}".format(u[0], u[1], u[2], u[3], u[4], u[5]))

def saveCSV(allUniv):
fp = open("univRank.csv", "w")
head = ["排名,", "名称,", "省市,", "类型,", "总分,", "办学层次,", "\n"]
fp.writelines(head)
for r in allUniv:
s = ",".join(r)
s+="\n"
fp.write(s)
fp.close()

def main(num):
url = "https://www.shanghairanking.cn/rankings/bcur/2023"
html = getHTMLText(url)
soup = BeautifulSoup(html, "html.parser")
fillUnivList(soup)
printUnivList(num)
saveCSV(allUniv)

main(20)

其他

参看模块文档

Shell 输入

1
python -m pydoc -p xxx

生成临时网页

whl

whl是Python库的一种打包格式,用于通过pip进行安装,相当于Python库的安装包文件。whl文件本质上是一个压缩格式文件,可以通过改扩展名为zip查看其中内容。whl格式用于替代Python早期的eggs格式,是Python打包格式的事实标准

python第三方库的安装

  • 使用pip
1
2
3
pip install -U pip # 更新pip版本
pip show []
pip search []
  • 文件安装
1
pip install <File.whl>

一行打印爱心字符

偶然看到这个东西, 通过列表的推导式一行生成二维字符画, 其实转化成正常的语句很容易看懂
主要难点在于图形的函数表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# print('\n'.join([''.join([('lovelovelove'[(x-y)%12]if((x*0.05)**2+(y*0.1)**2-1)**3-(x*0.05)**2*(y*0.1)**3<=0 else' ')for x in range(-30,30)])for y in range(15,-15,-1)]))


output = []
for y in range(15, -15, -1):
line = []
for x in range(-30, 30):
if ((x * 0.05) ** 2 + (y * 0.1) ** 2 - 1) ** 3 - (x * 0.05) ** 2 * (y * 0.1) ** 3 <= 0:
line.append('lovelovelove'[(x - y) % 12])
else:
line.append(' ')
output.append(''.join(line))

print('\n'.join(output))

参考

  1. python官方教程
  2. [python语言程序设计基础(第二版)]
  3. www3schools
  4. python中的彩蛋
  • Author:

    slacr_

  • Copyright:

  • Published:

    September 6, 2023

  • Updated:

    September 6, 2023

Buy me a cup of coffee ☕.

1000000