获得用户输入数字N,计算并输出从N开始的5个质数,单行输出
首先:定义函数判断一个数是否是质数,return True/False,注意return True的格式,不在for循环体中,在函数体中(循环的高级用法,for---else);其次:确定输入的数、计数为0;最后while循环,计数5次,在循环中调用判断是否是质数的函数,是就打印出来,计数加一,再将输入的数加一。注意:输入的数加一,要在if循环外,若在里面就不会继续判断了!
def prime(m):
for i in range(2,m):
if m % i == 0:
return False
return True
n = eval(input())
nt = int(n)
nt = nt + 1 if nt < n else nt
count = 0
while count < 5:
if prime(nt):
print(nt,end=',')
count += 1
nt += 1
代码的改进:可以先将输出质数个数设出来,count=5,在while循环中依次减一,便于参数的修改!若要求输出时,数据用逗号分割,最后一个不用逗号:print(mt,end=',') print(mt,end='')
def zhi(n):
for i in range(2,n):
if n % i == 0:
return False
return True
m = eval(input())
mt = int(m)
mt = mt+1 if mt < m else mt
count = 5
while count > 0:
if zhi(mt):
if count > 1:
print(mt,end=',')
else:
print(mt,end='')
count -= 1
mt += 1
画同心圆
import turtle turtle.pensize(2) turtle.circle(10) turtle.circle(40) turtle.circle(80) turtle.circle(100)
画五角星
from turtle import *
color('red','red')
begin_fill()
for i in range(5):
fd(200)
rt(144)
end_fill()
done()
import 模块:导入一个模块,每次使用模块中的函数都要是定是哪个模块
from...import *:导入一个模块中的所有函数,每次使用模块中的函数直接使用函数就可。因为已经知道该函数是那个模块中的了。
from...import:导入一个模块中的一个函数
import support
support.print_func("Runoob")
from support import *
print_func("Runoob")
温度转换:摄氏度——标准大气压下水的结冰点为0度,沸点为100度;华氏度——标准大气压下水的结冰点为32度,沸点为212度。
需求分析:将摄氏度转为华氏度,或将华氏度转为摄氏度。
分析问题:理解1,直接将温度值进行转换;理解2,将温度信息发布的声音或图像形式进行理解和转换;理解3,监控温度信息发布渠道,实时获取并转换温度值。(采用理解1)
划分边界:I—带华氏或摄氏标志的温度值,P—选择适当的温度转换算法,O—带华氏或摄氏标志的温度值
设计输入输出格式:标识放到温度最后,F表示华氏度,C表示摄氏度(82F表示82华氏度)
设计算法:根据华氏和摄氏温度定义,利用转换公式:C=(F-32)/1.8 F = c*1.8+32
TempStr = input("请输入带有符号的温度值:")
if TempStr[-1] in ['F','f']:
C = (eval(TempStr[0:-1]) - 32)/1.8
print("转换后的温度是{:.2f}C".format(C)) #若计算较为复杂可先把C的式子列出来,若较简单可直接再print的format中进行
elif TempStr[-1] in ['C','c']:
F = 1.8*eval(TempStr[0:-1]) + 32
print("转换后的温度是{:.2f}F".format(F))
else:
print("输入格式错误")
请输入带有符号的温度值:80f 转换后的温度是26.67C >>> ==================== RESTART: F:PYECourseTempConvert.py ==================== 请输入带有符号的温度值:78c 转换后的温度是172.40F
举一反三:货币转换、重量转换、面积转换
“温度转换”实例编程理解:
代码高亮:编程的色彩辅助体系,不是语法要求。
缩进:表达程序格式框架,表达代码间包含和层次关系;4个空格/1个TAB
注释:辅助说明信息。单行注释—#开头,多行注释:'''开头和结尾(3个单引号),不被计算机程序运行。
变量:程序中用于保存和表示数据的占位符号。TempStr是变量名字,用=向变量赋值
命名:大小写字母、数字、下划线和汉字等字符及组合,大小写敏感、数字不能用开头,不能用保留字(33个,编程语言的基本单词)。如TempStr。
数据类型:10,011,101表示啥意思呢?数字类型:整数- 10011101;浮点数-带小数
字符串类型:"10,011,101";字符串的序号有正向递增序号(0开始)和反向递减序号(-1开始)。获得字符串中的一个或多个字符——索引:返回字符串中的单个字符,<字符串>[M],如TempStr[-1];切片:返回字符串中的一段字符串<字符串>[M:N],如TempStr[0:-1]表示从0开始但不到最后一个字符。
列表类型:[10,011,101](表示3个数)['F','f']表示两个元素'F'和'f',可用保留字in判断元素是否在列表中
赋值语句:由赋值符号(=)构成的一行代码,右侧的数据类型同时作用于变量,TempStr=input( ),input( )返回一个字符串,TempStr变量也是一个字符串。
分支语句:if elif else构成条件判断的分支结构,保留字所在行的最后存在一个冒号
函数:一个名字+一个括号,如input( )、eval( )、print()根据输入参数产生不同输出的功能过程,<函数名>(<参数>)。
输入函数:input( )函数,<变量> = input(<提示信息字符串>),如TempStr = input("请输入")
输出函数:1、print( )函数,print(<拟输出字符串/字符串变量>),如print("输入格式错误")
2、print( )函数的格式化,如print("转换后的温度是{:.2f}C".format(C)) 字符串中出现了大括号,{ }表示槽,后续变量嵌入到槽中,槽中可以嵌套槽,用来表示宽度、填充等含义。 :.2f仅输出小数点后两位。
eval( )函数:评估函数,去掉参数最外侧引号并执行余下语句
C = (eval(TempStr[0:-1]) - 32)/1.8
eval(TempStr[0:-1]) 对TempStr除去最后一位之外的其他位进行评估运算,如用户输入82F,TempStr[0:-1] —— 去掉最后一位F获得一个字符串82; eval( )—— 变成数字类型,产生整数82
例:数字转换,获得用户输入的一个正整数输入,输出该数字对应的中文字符表示。
列表也是从0开始的,所以与变量的字符串相对应!
template = "零一二三四五六七八九"
a = input()
for i in a:
print(template[eval(i)],end='')
791 七九一
print()函数中增加end=" "参数表示输出后不增加换行,多个print()可以连续输出
print(" ", )中间加逗号,输出的字符串之间会增加空格。
for i in range (5):
print("Hello:",i)
Hello: 0 Hello: 1 Hello: 2 Hello: 3 Hello: 4
Python蟒蛇绘制 (run modle/F5运行)
import turtle
turtle.setup(650,350,200,200)
turtle.penup()
turtle.fd(-250)
turtle.pendown()
turtle.pensize(25)
turtle.pencolor("purple") #准备工作,确定起画位置、画笔大小、画笔颜色
turtle.seth(-40) #改变方向非常重要!图1为改变方向,图2为没变方向
for i in range(4):
turtle.circle(40,80)
turtle.circle(-40,80) #4个循环绘制了蟒蛇4个关节
turtle.circle(40,80/2) #半个关节弧长的一半
turtle.fd(40)
turtle.circle(16,180)
turtle.fd(40*2/3)
turtle.done() #程序运行后需手动退出
理解turtle.seth() + turtle.circle():改变方向后,可想象沿该方向画直线,circle的第一个参数表示圆的半径,若为正向左画(图13),若为负向右画(图24),第二个参数表示角度所对应的弧长。
#图0 import turtle turtle.circle(40,80) #图1 import turtle turtle.seth(-40) turtle.fd(100) turtle.circle(40,80) #图2 import turtle turtle.seth(-40) turtle.fd(100) turtle.circle(-40,80) #图3 import turtle turtle.seth(40) turtle.fd(100) turtle.circle(40,80) #图4 import turtle turtle.seth(40) turtle.fd(100) turtle.circle(-40,80)
举一反三:程序参数的改变——修改蟒蛇颜色,蟒蛇长度(1节、3节、10节),蟒蛇走向(向左走、斜着走)。计算问题的拓展——圆形、五角星、国旗、机器猫绘制,掌握绘制一条线的方法就可以绘制整个世界。
import 保留字引入了一个绘图库:turtle(海龟库)1969年诞生,用于程序设计入门;python语言的标准库之一;入门级的图像绘制函数库。turtle是一种真实的存在,一只海龟在窗体正中心、在画布上游走,走过的轨迹形成了绘制的图形,海龟由程序控制,可以变换颜色、改变宽度。
turtle的绘图窗体:(绘制100长的直线指的是100像素长的直线)
turtle.setup(width, height, startx, starty)包括4个参数:宽度,高度,起始点xy的坐标(窗体左上角位置坐标:相对于屏幕左上角的坐标,可选)。setup( )函数非必须,只在需要设置窗体大小、在屏幕中显示位置的时候才需要。
turtle的行进:画布上以中心为原点 走直线&曲线(绝对坐标&海龟坐标)
turtle.goto(x,y):让在任何位置的海龟去到指定的坐标位置。
turtle.forward(d) 别名turtle.fd(d) :正前方行进,海龟走直线 d为行进距离,可为负数
turtle.bk( ):向海龟的反方向行进;
turtle.circle(r,extent=None):r-半径(默认圆心在海龟左侧距r处,海龟处在圆的最低点),extent-绘制的弧度。 注意圆心的位置!!!
turtle的行进方向:(绝对角度&海龟角度)
turtle.seth(angle),改变海龟行进方向但不行进,+ turtle.fd( )朝着当前设定的方向直线运行。
turtle.left(angle)、turtle.right(angle)用左右的方式改变运行角度。
常用的RGB色彩:每色取值范围整数0-255或0-1小数,turtle默认小数值,可切换为整数值。
turtle.colormode(1.0):RGB小数模式;turtle.colormode(255):RGB整数值模式。
库引用:扩充python程序功能的方式。使用import保留字完成。三种方式:
import<库名> import turtle 引入turtle库
<库名>.<函数名>(<函数参数>) turtle.setup(650,350) 使用turtle库函数完成功能
from <库名> import * from turtle import *
<函数名>(函数参数) setup(650,350)
import <库名> as <库别名> import turtle as t 给库关联一个更短、更适合自己的名字
<库别名>.<函数名>(<函数参数>)
from <库名> import <函数名>
第一种方法不会出现函数重名问题(<库名>.<函数名>是新程序中的函数名); 第二种方法会出现(库中的某个函数名称可能与用户自定义的函数名称一致,导致函数名字发生冲突);若程序很短,只使用了这个库,没有自己定义的函数,可使用from<库名> import *的形式。
turtle画笔控制函数
turtle.penup( ) 别名turtle.pu( ) :抬起画笔,海龟在飞行
turtle.pendown( ) 别名turtle.pd( ) :落下画笔,海龟在爬行
抬起画笔、落下画笔,一般成对出现,去到想去的地方,而不留痕迹!!!
注意与函数goto( )的区别,抬起画笔+fd( )/goto( )+落下画笔 确定画的起点,不会画出实际线条。
turtle.pensize(width) 别名turtle.width(width):画笔宽度,海龟的腰围
turtle.pencolor(color) color有3种形式,颜色字符串或r,g,b值:画笔颜色,海龟在涂装turtle.pencolor("purple") / turtle.pencolor(0.63,0.13,0.94) / turtle.pencolor((0.63,0.13,0.94))---元组值是指将小数值或整数值形成一个独立元素,如(0.63,0.13,0.94)
循环语句:for in range 按照一定次数循环执行一组语句。
for <变量> in range(<参数>)
<被循环执行的语句>
range的参数就是循环的次数,缩进的代码将被循环执行;for in 之间的变量表示每次循环的计数,0 — 次数-1。
range( )函数:产生循环计数序列,最主要作用是和for in 搭配形成计数循环。
range(N):产生0到N-1的整数序列,共N个。如range(5) 0,1,2,3,4
range(M,N):产生M到N-1的整数序列,共N-M个。如range(2,5) 2,3,4
例:turtle风轮绘制
import turtle as t
t.pensize(2)
for i in range(4):
t.left(90)
t.fd(150)
t.right(90)
t.circle(-150,90/2)
t.goto(0,0)
t.left(135)
import turtle as t
t.pensize(2)
for i in range(4):
t.seth(90*i)
t.fd(150)
t.right(90)
t.circle(-150, 45)
t.goto(0,0)
个人感悟:for in range循环在绘图种的作用:复制粘贴。不要把turtle.circle()想得太复杂,直接在点上绘制弧度对应的弧长即可,注意是哪个方向。第3张图为没有加 t.right(90),图像方向改变可想象为一条虚线,即辅助线;
整数类型:可正可负。pow(x,y)函数:计算x的y次方,想算多大算多大。
>>> pow(2,100) 1267650600228229401496703205376 >>> pow(2,pow(2,15)) 14154610310449547890015530277449516013481307114723881672343857482723666342408452…
四种进制表示形式:a.十进制 如1010,99 b.二进制 — 以0b或0B开头 如0b010,0B101 c.八进制 — 以0o或0O开头 如0o123,0O456 d.十六进制 — 以0x或0X开头 如0x9a,-0x89
浮点数类型:带有小数点及小数的数字,浮点数的取值范围和小数精度都存在限制(取值范围数量级为-10的308次方—10的308次方,精度数量级围为10的-16次方),但常规计算可忽略。浮点数间的运算存在不确定尾数,不是bug。
>>> 0.1+0.3 0.4 >>> 0.1 + 0.2 0.30000000000000004 #不确定尾数造成的 >>> 0.1 + 0.2 == 0.3 False >>> round(0.1+0.2,1) == 0.3 True
浮点数间运算可能会产生不确定尾数。原因是,计算机中所有数字都采用二进制方式表示,用53位二进制表示小数部分。0.1表示为0.00011001100110011001 10011001100110011001 1001100110011010(二进制)。二进制与十进制不存在严格对等关系,所以二进制表示小数,会无限接近,但不完全相同。0.1表示为0.1000000000000000055511151231257827021181583404541015625(十进制),只输出前16位小数。所以0.1+0.2计算时,在计算机内部经过二进制转换,再经过二进制运算,再反向转换为十进制小数时,结果会无限接近0.3,但可能出现一个不确定的尾数。
round(x,d )函数:对x四舍五入,d是小数截取位数。浮点数间运算及比较,用round()函数辅助。
int(x):取整,简单截取,不是四舍五入。
浮点数可以以用科学计数法表示,使用字母e或E作为幂的符号,以10为基数,格式为e 表示 a*10b 如:4.3e-3 值为0.0043 9.6E5 值为960000.0
复数类型
如果x2 = -1,那么x的值是什么?
如 z = 1.23e - 4 + 5.6e + 89j,z.real 获得实部,z.imag获得虚部。
复数类型在常规编程中很少使用,但却是进行空间变换,尤其是跟复变函数相关的科学体系中最常用的一种类型。
数值运算操作符
//和%配合完美
二元操作符:两个数运算后,去更改其中的一个数。
x +=y / x-=y / x*=y / x/=y / x//=y / x%=y / x**=y 如x**=3与x = x**3等价
数字类型间可进行混合运算,生成结果为"最宽"类型。 整数 -> 浮点数 -> 复数(逐渐变宽),浮点数是虚部为0的复数。如123 + 4.0 = 127.0(整数+浮点数=浮点数,浮点数再经过运算时可能会产生不确定的尾数)
数值运算函数:以函数形式提供的数值运算功能
每天进步/退步1‰,累计进步/退步多少?
dayup = pow(1.001,365)
daydown = pow(0.999,365)
print("向上:{:.2f},向下:{:.2f}".format(dayup,daydown))
向上:1.44,向下:0.69
5‰和1%的力量
dayfactor = 0.005 #运用变量,一处修改即可。 =0.01
dayup = pow(1+dayfactor,365)
daydown = pow(1-dayfactor,365)
print("向上:{:.2f},向下:{:.2f}".format(dayup,daydown))
向上:6.17,向下:0.16 #向上:37.78,向下:0.03
使用变量的好处:一处修改即可,只需在变量赋值的地方修改一处,相关结果会发生变化。
工作日的力量(工作日每天进步1%,休息日每天退步1%)
从数学思维转为用计算机程序解决问题的计算思维(for in range)!!!用计算机程序来模拟365的过程,抽象+自动化。遇到工作日向上增加,遇到休息日向下减少,累计循环。
dayup = 1
dayfactor = 0.01
for i in range(365):
if i%7 in [0,6]:
dayup = dayup*(1-dayfactor)
else:
dayup = dayup*(1+dayfactor)
print(dayup)
a = pow(1.01,260)
b = pow(0.99,105)
c = a*b
print(c)
4.626500529730141 4.626500529730134
工作日的努力
A君:每天进步1%,不停歇。B君:每周工作5天休息2天,休息日下降1%,要多努力才能和A同?
"笨办法"试错(def..while..),让B尝试工作日达到一个什么样的能力值,能够超过A君。不断增加B的能力值,直到达到A君的效果。函数就像是数学中中含未知数x的等式,x就是定义函数中的占位符。然后再笨办法试错,算出未知数x。
从程序设计上来说,我们需要一段函数,它能够根据不同的努力值来计算工作日模式下的累积效果。为了能复用这段代码,需要编写一段函数(代码的组合)
函数的基本代码框架:def dayup(df) 参数df是一个占位符,用df表示dayfactor的简写,记得返回return dayup。
def dayUP(df):
dayup = 1
for i in range(365):
if i % 7 in [6,0]:
dayup = dayup * (1 - 0.01)
else:
dayup = dayup * (1 + df)
return dayup
dayfactor = 0.01
while dayUP(dayfactor) < 37.78:
dayfactor += 0.001
print("工作日的努力参数是:{:.3f}".format(dayfactor))
工作日的努力参数是:0.019
举一反三:如果休息日不下降呢? 如果工作如提高1%,休息日下降1‰呢? 如果工作3天休息1天呢? 如果“三天打鱼,两天晒网”呢?
字符串表示方法:a.由一对单引号表示 b.由一对双引号表示 c.由一对3单引号表示 d.由一对3双引号表示(a.b表示单行字符串,c.d表示多行字符串)
注:3单引号可以当多行注释,3单引号构成字符串,若在程序中出现一个字符串,字符串并没有给到某一个变量中或者没有进行任何操作,那么它也可以当注释来使用。
为啥要由两类四种表示呢?若在字符串中出现双引号,字符串可以用单引号表示;若字符串中出现单引号和双引号,字符串可以用3单引号表示。若在字符串中出现双引号,字符串也想用双引号表示,则可以用转义符 :表达字符的本意。如"这里有个双引号(")" 结果为这里有个双引号(")。转义符还可以形成一些组合,表达一些不可打印的含义:b 回退,n 换行(光标移动到下行首), r 回车(光标移动到本行首)
字符串的两个重要操作:索引和切片。
<字符串>[M:N] 如“零一二三四五六七八九十"[:3] 结果是"零一二"
<字符串>[M:N:K] 根据步长K对字符串切片 如“零一二三四五六七八九十"[1:8:2] 结果是"一三五七" “零一二三四五六七八九十"[::-1] 结果是"是、十九八七六五四三二一零"(字符串从最开始到最结尾,步长为-1,指从后向前逐一地取出 将字符串逆序)
字符串操作符
x + y :连接字符串x和y
n * x 或 x * n :将字符串x复制n次
x in s :如果x是s的字串,返回True,否则返回False
weekStr = '一二三四五六日'
weekId = eval(input("输入星期数字(1-7):"))
print("星期" + weekStr[weekId - 1])
weekStr = '星期一星期二星期三星期四星期五星期六星期日'
weekId = eval(input("请输入星期数字(1-7):"))
pos = (weekId - 1)*3
print(weekStr[pos:pos+3])
输入星期数字(1-7):5 星期五
字符串处理函数(字符串6个重要函数)
len(x) :返回字符串x的长度 如len("一二三456")结果为6 注:数字/标点符号/字母/汉字都为1字符
str(x) :转换为字符串类型 如str(1.23)结果为"1.23" str([1,2])结果为"[1,2]" 与eval( )函数功能相反
hex(x) 或 oct(x) :整数x的十六进制或八进制形式的字符串。 如hex(425)结果为"0x1a9" oct(425)结果为"0o651" hexadecimal[ˌheksəˈdesɪml]十六进制的,octagon[ˈɒktəgən]八边形
二进制:0b 或 0B 开头 八进制:0o 或 0O 开头 十六进制:0x 或 0X 开头
chr(u) :u为Unicode编码——返回对应的字符; ord(x) :x为字符——返回对应的Unicode编码
Unicode编码是python字符串的编码形式,python所有字符串、代码都是采用Unicode编码。计算机是由欧洲和美国人发明的,所以最开始计算机中只有英文字符,英文字符的空间范围有限,国际上广泛使用ASCII码来表示所有的英文字符。随着计算机广泛应用到世界各地,如何对中文字符进行编码,如何让计算机可以处理中文汉字?用一套编码覆盖世界上所有的字符,即Unicode编码。从0到1114111(十六进制0x10FFFF)空间,每个编码对应一个字符。
>>> "1 + 1 = 2" + chr(10004)
'1 + 1 = 2✔' #10004对应的字符是✔
>>> "这个字符♉的Unicode值是:" + str(ord("♉"))
'这个字符♉的Unicode值是:9801' #金牛对应的编码是9801,金牛座是十二星座第二位
for i in range(12):
print(chr(9800 + i),end="")
♈♉♊♋♌♍♎♏♐♑♒♓ #通过Uincode输出十二星座字符
学完python语言程序设计内容,记得去看《python密码学编程》,完成恺撒密码加密算法,第3章的程序设计题。
恺撒密码加密破译
s = input()
t = ""
for c in s:
if 'a' <= c <= 'z':
t += chr( ord('a') + ((ord(c)-ord('a')) + 3 )%26 )
elif 'A' <= c <= 'Z':
t += chr( ord('A') + ((ord(c)-ord('A')) + 3 )%26 )
else:
t += c
print(t)
python is good sbwkrq lv jrrg
字符串处理方法(字符串8个重要方法)
方法:.( )风格中的函数( );方法本身也是函数,但与有关.( )风格使用。字符串及变量也是,存在一些方法。注:.( )风格也是面向对象的一种使用风格,a为对象,b是某一对象能够提供的功能,即方法。方法必须用.的形式来执行。
str.lower( )或str.upper( ) :全部字符串小写/大写 如"AbCdEfGh".lower( )结果为"abcdefgh"
str.join(iter) :在每个字符间加入一个str字符 如",".join("12345") 结果为"1,2,3,4,5"
str.split(sep=None) :字符串分割符 如 "A,B,C".split(",")结果为['A','B','C'] !!!分割字符要加引号!默认以空格的形式对字符串分隔,以列表形式返回变量,里边的每个元素就是空格分开的单词。把一个大元素按要求劈成若干小元素
str.strip(chars) :去掉最左侧和右侧的字符 如"= python=".strip(" =np") 结果为"ytho"
str.count(sub) :用于计数,如"an apple a day".count("a")结果为4
str.replace(old,new) :把原字符串替换成新字符串 如"python".replace("n","n123.io")结果为"python123.io"
str.center(width[,fillchar]) :将字符串位于居中位置,中间字符串一定有宽度,左右两侧一定会有填充存在 如"python".center(20,"=") 结果为'=======python======='
" i,love,python ".strip().split(',')
Out[10]: ['i', 'love', 'python']
字符串类型的格式化(槽机制+format方法) { } + ( )
格式化是对字符串进行格式化表达的方式。槽相当于一个占位信息符,用一对{}表示,只在字符串中有用。
字符串格式化的用法:<模板字符串>.format<逗号分隔的参数>
槽内部格式化的配置方式:{<参数序号> : <格式控制标记>} 6个格式控制参数分两组
:后面数字---输出宽度,出现.---精度,出现,---千位分隔符,出现><^---对齐,出现字母---类型
format( )可以槽嵌套槽,表示宽度、填充含义。print("{0:^{1}}".format('*'*i,n)),用户输入的数据不确定,使行的宽度也不确定,通过嵌套槽为n来确定宽度。
例:读入一个整数N,N是奇数,输出由星号字符组成的等边三角形,要求:第1行1个星号,第2行3个星号,第3行5个星号,依次类推,最后一行共N的星号。
注:s='PYTHON' print("{0:3}".format(s)) 结果为PYTHON,而不是PYT
n = eval(input())
for i in range(1,n+1,2):
print("{0:^{1}}".format('*'*i,n))
5 * *** *****
time库:python中处理时间的标准库。能表达计算机时间、获取系统时间并格式化输出、提供系统级的精确计时功能,用于程序性能分析。 import time time.( )
time库包括三类函数:时间获取、时间格式化、 程序计时
时间获取
time( ):获取当前时间戳(当前系统中表示时间的一个浮点数)表示从1970年1月1日0:00开始到当前时刻为止的以秒为单位的数值。
ctime( ):获取当前时间并以易读的方式表示。time库中获取人类译读方式时间的最简单的函数。
gmtime( ):生成计算机程序可处理的时间格式。
>>> import time >>> time.time() 1645008151.1828973 >>> time.ctime() 'Wed Feb 16 18:45:12 2022' >>> time.gmtime() time.struct_time(tm_year=2022, tm_mon=2, tm_mday=16, tm_hour=10, tm_min=47, tm_sec=41, tm_wday=2, tm_yday=47, tm_isdst=0)
时间格式化:将时间以合理方式展现出来。类似于字符串格式化(.format),需要有展示模板;展示模板由特定的格式化控制符组成;
strftime(tpl,ts ):tpl是格式化模板字符串,ts是计算机内部时间类型变量。所有的控制符都是%+字母 的形式表达,%Y:年份(0000-9999),%m:月份(01-12),%B:月份名称(January-December),%b:月份名称缩写(Jan-Dec),%d:日期(01-31),%A:星期(Monday-Sunday),%a:星期缩写(Mon-Sun),%H:小时(24h制 00-23),%I:小时(12h制 00-12),%p:上/下午(AM,PM),%M:分钟(00-59),%S:秒(00-59)
年、月、日是大写,小时、分种、秒是小写。
???strftime( )中添加ts变量时间反而是错的,不添加反而是对的咋回事呢?
strptime(str,tpl ):str是字符串形式的时间值,tpl是格式化模板字符串,用来定义输出效果。与strftime( )互补。将一个字符串变为计算机内部可以操作的一个时间。
>>> time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime())
'2022-02-16 11:30:05'
timeStr = '2022-02-16 18:45:12'
>>> time.strptime(timeStr,"%Y-%m-%d %H:%M:%S")
time.struct_time(tm_year=2022, tm_mon=2, tm_mday=16, tm_hour=18, tm_min=45, tm_sec=12, tm_wday=2, tm_yday=47, tm_isdst=-1)
程序计时:测量起止动作所经历的时间
perf_counter( ):返回一个CPU级别的精准时间计数值,单位为秒,由于计数值起点不确定,连续调用差值才有意义。
sleep(s):s为拟休眠时间,单位为秒,可以是浮点数。
>>> start = time.perf_counter() >>> end = time.perf_counter() >>> end - start 23.1431617 >>> def wait(): time.sleep(3.3) >>> wait() #程序将等待3.3s,然后再向前运行
文本进度条:用字符串的方式,打印可以动态变化的文本进度条;进度条需要能在一行中逐渐变化。进度条反映某一个事件的运行,与时间有关系,故需模拟一个持续的进度——sleep()函数。
import time
scale = 10 #文本进度条的大概宽度
print("------执行开始------")
for i in range(scale+1):
a = '*' * i #字符串与整数的乘积表示字符串被复制的次数
b = '.' * (scale - i)
c = (i/scale)*100 #与字符串进度一致的百分比
print("{:^3.0f}%[{}->{}]".format(c,a,b)) #设置了3个槽(填充、对齐、宽度)
time.sleep(0.1)
print("------执行结束------")
------执行开始------ 0 %[->..........] 10 %[*->.........] 20 %[**->........] 30 %[***->.......] 40 %[****->......] 50 %[*****->.....] 60 %[******->....] 70 %[*******->...] 80 %[********->..] 90 %[*********->.] 100%[**********->] ------执行结束------
文本进度条单行动态刷新:根据程序的进度不断显示文本进度条的信息。刷新的本质是用后打印的字符覆盖之前的字符,要求不能换行—print( )需要被控制(在print函数中增加,end=" ",光标停留在字符串后面,不会换行,仅不换行就赋值为空,若要增加信息在end参数中增加);要能回退—打印后光标退回到之前的位置r(在输出字符串前使光标退回到当前行首)
import time
for i in range (101):
print("r{:3}%".format(i),end="") #要输出字符串,但输出前先把光标放行首再输出,输出后不换行,循环
time.sleep(0.1)
注意:IDLE中F5键执行代码,无刷新效果,所有信息都打印出来。因为IDLE是编写程序的开发环境,不是程序运行的主要环境,为保证其中参数运行的效果,把r功能屏蔽掉了。
实例:文本进度条
import time
scale = 50
print("执行开始".center(scale//2,'-'))
start = time.perf_counter()
for i in range (scale + 1): #range (scale)取不到scale,range(scale+1)才能取到scale
a = '*' * i #'*'和'.'数量和为50
b = '.' * (scale - i)
c = (i/scale)*100 #i最大值为scale50,(i/scale)*100=100完成全部进度
dur = time.perf_counter()-start #time.perf_counter()为计时,与程序运行时间有关,与scale无关
print("r{:^3.0f}%[{}->{}]{:.2f}s".format(c,a,b,dur),end='')
time.sleep(0.1)
print("n"+"执行结束".center(scale//2,'-'))
-----------执行开始---------- 100%[**************************************************->]5.45s -----------执行结束----------
在打印“执行输出”两侧通过“-”字符来构成线条,a.直接打印输出。b..center( )方法,包括两个参数:字符串长度和填充符号。//表示整数商 10//3 结果为 3 c.字符串槽内部的格式化,填充对齐宽度,但得作用在槽内,槽机制+format方法
time库计时使用perf_counter()函数 start = time.perf_counter() dur = time.perf_counter() - start .注意进度百分号要没有小数点,时间保留两位小数点。
message = '执行开始'
print("{:-^25}".format(message)) #字符串的填充对齐宽度,需要作用在槽中,槽机制+format方法
print("----------执行开始-----------")
print("执行开始".center(25,'-')) #25表示输出字符串的总长度
----------执行开始-----------
----------执行开始-----------
-----------执行开始----------
举一反三:perf_counter( )计时 可以比较部分程序运行时间,统计程序中可能消耗大量运行时间的部分。在运行时间需要较长的程序中增加进度条;在任何希望提高用户体验的应用中增加进度条。
文本进度条的不同设计函数:
什么样的进度条展示模式让用户体验更好,相比线性展示,开始展示进度条速度慢些,随着持续下载,后续进度条展示的增长效果组件增加,更符合人类需求。
程序结构:线性结构、分支结构(单分支结构、二分支结构、多分支结构、条件判断及组合、程序的异常处理)、循环结构(遍历循环---对应保留字for、无限循环---对应保留字while、循环控制保留字、循环的高级用法)
单分支语句:if
guess = eval(input())
if guess == 99:
print("猜对了")
二分支结构:if — else
紧凑形式 <表达式1> if <条件> else <表达式2> print("猜{ }了".format("对" if guess == 99 else "错")) ,判断if条件,若guess的值=99,返回前面的“对”,否则返回后面的字符串“错”。紧凑形式if 、else所对应的输出不是语句,是表达式,表达式是语句的一部分(简单理解为带赋值形式的有等号构成的语句,字符串“对”、“错是语句中的一部分,没有赋值的过程”)
guess = eval(input())
if guess == 99:
print("猜对了")
else:
print("猜错了")
guess = eval(input())
print("猜{}了".format("对" if guess==99 else"错"))
guess = eval(input())
if True: #后一部分是不会执行的
print("猜对了")
else:
print("猜错了")
多分支结构:if - elif - elif - elif /if - elif - else 注意多条件之间的包含关系、变量取值范围的覆盖
score = eval(input())
if score >= 60:
grade = 'D'
elif score >= 70:
grade = 'C'
elif score >= 80:
grade = 'B'
elif score >= 90:
grade = 'A'
print("输入成绩属于级别{}".format(grade))
80
输入成绩属于级别D
#正常运行,但逻辑错误!
只要遇到if True,后边的语句就会被执行;not True相当于False,不会执行语句块2 ,只会执行else部分的语句块1
if True: if not True: print("条件正确") print("语句块2") else: print(“语句块1”)
条件判断的操作符
<小于 <=小于等于 >= 大于等于 >大于 ==等于 !=不等于
条件组合的保留字:
x and y :条件x和条件y的逻辑与 ;x or y :条件x和条件y的逻辑或;not x:条件x的逻辑非
guess = eval(input())
if guess > 99 or guess < 99: #既使用了条件判断操作符又使用了条件组合保留字
print("猜错了")
else:
print("猜对了")
程序的异常处理
num = eval(input("请输入一个整数: ")) print(num**2) 当用户没有输入整数时,会产生异常。会提示异常发生的代码行数、异常类型、异常内容提示。使用保留字 try - except .要执行的内容放try的语句块1中。有异常,执行except的语句块2。无异常,执行语句块1----执行后续语句。在except中可增加异常类型,仅针对一种类型。
异常处理的高级使用:try - except - else - finally,finally对应的语句块4一定执行,else对应的语句块3在不发生异常时执行。(先执行try,没异常,奖励执行else;有异常,执行except;最后都要执行finally)
try: try: try: <语句块1> <语句块1> <语句块1> except: except <异常类型>: except: <语句块2> <语句块2> <语句块2> else: <语句块3> finally: <语句块4>
try:
num = eval(input("请输入一个整数:"))
print(num**2)
except:
print("输入不是整数")
try:
num = eval(input("请输入一个整数:"))
print(num**2)
except NameError: #except + 异常名字 针对这一个异常类型
print("输入不是整数")
实例5:身体质量指数BIM BMI = 体重 (kg) / 身高2 (m2) 有国际、国内分类
问题需求:同时输入体重、身高数据,同时输出国内、国际BMI指标分类信息
思路:分别计算并给出国内和国际的BMI分类;混合计算并给出国内和国际的BMI分类(求同存异)
注意:同时赋值不能写成这样:who = " ",nat = " ",应该是who,nat = "",""
height,weight = eval(input("输入身高和体重数据[用逗号分隔]:"))
bmi = weight / pow(height,2)
print("BMI 数值为{:.2f}".format(bmi))
who,nat = "",""
if bmi < 18.5:
who,nat = '偏瘦','偏瘦'
elif 18.5 <= bmi < 24:
who,nat = '正常','正常'
elif 24 <= bmi < 25:
who,nat = '正常','偏胖'
elif 25 <= bmi < 28:
who,nat = '偏胖','偏胖'
elif 28 <= bmi < 30:
who,nat = '偏胖','肥胖'
else:
who,nat = '肥胖','肥胖'
print("BMI指标为:国际{0},国内{1}".format(who,nat))
输入身高和体重数据[用逗号分隔]:1.60,48
BMI 数值为18.75
BMI指标为:国际正常,国内正常
遍历循环:遍历某个结构形成的循环运行方式。由for + in 组成,从遍历结构中逐一提取元素,放在循环变量中。完整遍历所有元素后结束。一串数、一个字符串、一个列表、一个文件……都是可以遍历的结构。
for <循环变量> in <遍历结构>:
<语句块>
计数循环(N/特定次):for in range(N) / for in range(M,N,K) 遍历range()函数产生的数字序列
for <循环变量> in range(N): for <循环变量> in range(M,N,K):
<语句块> <语句块> #从M开始,到N之前的整数,以K为步长
for i in range(1,6,2):
print("Hello:",i)
Hello: 1
Hello: 3
Hello: 5
字符串遍历循环:s为字符串,遍历整个字符串,产生循环。
for c in s:
<语句块>
for c in "python123":
print(c,end=',')
p,y,t,h,o,n,1,2,3,
列表遍历循环:ls为列表,遍历其每个元素,产生循环。注:遍历列表不会把列表中的,打印
for item in ls:
<语句块>
for item in [123,'PY',456]:
print(item,end=',')
123,PY,456,
文件遍历循环:fi是一个文件标识符,遍历其每行,产生循环。(一个外部文件通过python函数打开,若是以字符形式打开就会表示为一个文件标识的名字,相当于用一个变量标识系统中的文件)
for line in fi:
<语句块>
for line in fi:
print(line)
优美胜于丑陋
明了胜于隐晦
简洁胜于复杂
如果出现两个未知数:“笨办法”,考虑 def + 循环。与天天向上例子关联。def 部分会有return,但有return False、return True,在后面调用函数时前面需要if(判断数是否是素数),return dayup(天天向上是返回一个数值,工作日需要多少努力)
例:求100以内所有素数之和。
def is_prime(n):
for i in range(2,n):
if n%i == 0:
return False
return True
sum = 0
for i in range(2,100):
if is_prime(i):
sum += i
print(sum)
1060
无限循环:由条件控制的循环运行方式,while。反复执行语句块,直到条件不满足时结束。
while <条件>:
<语句块>
a = 3
while a > 0:
a = a -1 #若修改为a = a + 1,程序将无限循环,永不退出,ctrl + c 组合键退出
print(a)
2
1
0
循环打断:使用保留字continue和break,continue为结束本次循环,break为结束整个循环
for i in range(1,11):
if i == 6:
break
print(i)
结果为1,2,3,4,5
for i in range(1,11):
if i == 6:
continue
print(i)
结果为1,2,3,4,5,7,8,9,10
循环的高级用法:循环+else。当循环没有遇到break语句时,执行else语句块(break相当于退出循环,break仅能退出最内层的当前循环)。else语句块作为“正常”完成循环的一种奖励(与异常处理else作用类似)。
for <循环变量> in <遍历结构>: while <条件>: <语句块1> <语句块1> else: else: <语句块2> <语句块2>
for c in 'PYTHON':
if c == 'T':
continue
print(c,end='')
else:
print("正常退出")
PYHON正常退出
for c in 'PYTHON':
if c == 'T':
break
print(c,end='')
else:
print("正常退出")
PY
例:计算1-2+3-4...966 关键:设初始为0
a = 0
for i in range(1,967):
if i%2 == 0:
a -= i #a = a - i
else:
a += i #a = a + i
print(a)
-483
a = 0
count = 1
while count <= 966:
if count % 2 == 0:
a -= count
else:
a += count
count += 1
print(a)
-483
例:用户登录,若首行输入用户名为‘Kate’,第二行输入密码为‘666666’,输出‘登录成功!’;当有3次输入用户名或密码不正确输出“3次用户名或者密码均有误!退出程序。”。关键:设初始次数为0,用户输入的名字和密码要在循环中,在else中累加登录次数,注:while :后为一整个循环体。
i = 0
while i < 3:
name = input()
key = input()
if name =='Kate' and key =='666666':
print("登录成功!")
break
else:
i += 1
if i == 3:
print("3次用户名或者密码均有误!退出程序。")
random库:是使用随机数的python标准库(自带库,不需要安装,直接import使用)。伪随机数:采用梅森旋转算法,生成的伪随机序列,序列中的元素为伪随机数,表现为随机数的形式
random库包括两类函数,常用8个。基本随机数函数:seed( )、random()
产生小数:random( )/uniform( ) 产生整数:randint( )/randrange( ) 序列选一:choice( )/shuffle( )
基本随机数函数:
种子只需给一次,随机数会随着每次调用而产生不同的随机数;也可不给种子,直接调用random产生随机数(默认的种子是第一次调用random函数所对应的系统时间,精确到微秒,很难再现)
为啥要给种子?因为如果编程中给出了随机种子,下一次程序再运行,只要种子相同,产生的随机数也相同,对于使用随机数的程序可以复现或再现程序运行过程。
在程序运行中如何利用seed( )函数呢?from...import 引入具体的函数,使用seed()需要提前引入
import random random.seed(10) random.random() Out[5]: 0.5714025946899135 random.random() Out[6]: 0.4288890546751146 import random random.seed(10) random.random() Out[9]: 0.5714025946899135 random.seed(10) random.random() Out[11]: 0.5714025946899135
from random import random, seed
DARTS = eval(input())
seed(123)
hits = 0.0
for i in range(DARTS):
x, y = random(), random()
dist = pow(x ** 2 + y ** 2, 0.5)
if dist <= 1.0:
hits = hits + 1
pi = 4 * (hits/DARTS)
print("{:.6f}".format(pi))
扩展随机数函数:
实例6:圆周率的计算
1、数学方法:
2、蒙特卡罗方法:圆的面积与方形面积之商与圆周率有关系。如何计算圆的面积?对一个区域面积,进行撒点,每个点随机出现在区域的任何一个位置。如果点尽可能的多且随机,圆内部的点构成了圆的面积,正方形中的所有点为正方形的面积。该方法还应用在很多工程问题中。
分析:1、无穷个数的累加:模拟一个很大的数,for循环实现累加。2、用随机数表示x,y的坐标,计算点到圆心的距离来判断点是在圆内还是方形内。
若代码特别长,在一行中无法表达,可在代码中增加“”(与除"/"相反)使代码换行。若多行代码放到一行,需添加";"。如s=[1,2,3,4,5,6,7,8,9];random.shuffle(s);print(s)
#数学公式方法,前提是知道公式
pi = 0
N = 100
for k in range(N):
pi += 1/pow(16,k)*( #pi += 1/pow(16,k)*( 4/(8*k+1)-2/(8*k+4)-1/(8*k+5)-1/(8*k+6))
4/(8*k+1)-2/(8*k+4)-
1/(8*k+5)-1/(8*k+6))
print("圆周率值是:{}".format(pi))
圆周率值是:3.141592653589793
#蒙特卡罗方法 先用整体的1/4
from random import random
from time import perf_counter #计时的函数
DARTS = 1000*1000 #区域中抛撒点的总数量
hits = 0.0 #在圆内部的点的数量
start = perf_counter() #启动计时
for i in range(1,DARTS+1): #for in循环模拟每次撒点
x,y = random(),random() #生成随机数的坐标值,random函数返回0-1之间的小数值
dist = pow(x**2+y**2,0.5) #计算点到圆心的距离,来判断点在圆内or方形内
if dist <= 1.0:
hits += 1
pi = 4 * (hits/DARTS)
print("圆周率值是:{}".format(pi))
print("运算时间是:{}".format(perf_counter()-start))
圆周率值是:3.141248
运算时间是:1.0513156000006347
举一反三:数学思维(找到公式,利用公式求解),计算思维(抽象一种过程,撒点过程,计算机自动求解)。程序运行80%的时间都花在10%的代码(循环)上,发现程序运行了较长时间,可以perf_counter去测量循环,再优化。
定义函数:一段代码;功能的抽象,函数表达特定功能。两个作用:降低编程难度 和 代码复用。
def 定义函数名,return给出返回值,中间是函数代码,名字后通过括号给出参数。指定的参数是占位符;参数是输入,函数体是处理,结果是输出;函数不经调用,不会被执行;
调用函数:调用时要用实际参数替换定义中的形式参数,函数调用后得到返回值。
执行代码a = fact(10)时,会去查找所定义的函数def fact (n),将给定的参数10赋给函数的参数n,(10代替了定义函数中那个的n),执行函数 体的相关程序(for i in range(1,n+1)中的n也会替换为10),运算代码后产生一个具体的s值,s值作为返回值(返回给fact(10)这行代码)赋值给a。
函数参数:函数可以有参数,也可以没有参数,但必须保留括号。
def <函数名>(<参数(0个或多个)>):
<函数体>
return <返回值>
#案例:计算n!
def fact(n):
s = 1
for i in range(1,n+1):
s *= i
return (s)
a = fact(10)
print(a) #结果为3628800
可选参数传递:函数定义时为某些参数指定默认值,构成可选参数(可以提供参数也可不提供参数)。可选参数须放在必选参数之后。
def <函数名>(<必选参数>,<可选参数>):
<函数体>
return <返回值>
#案例:计算n!//m(//表示整除)
def fact(n,m=1):#给出了第二个参数(可选参数),就用实际值;若没有给,就把m设为1进行下面的运算
s = 1
for i in range(1,n+1):
s *= i
return (s//m)
a = fact(10) #调用时可以使用第二个参数,也可不使用
print(a) #结果为3628800
a = fact(10,5) #调用时可以使用第二个参数,也可不使用
print(a) #结果为725760
可变参数传递:不定参数总数量。必选参数放前面,最后增加 *b表达不确定的参数(*a、*c都行),for item in b:
应用:python提供的函数max和min,计算一组数据的最大值和最小值,其参数是不确定的
def <函数名>(<参数>, *b):
<函数体>
return <返回值>
例:计算n!乘数
def fact(n,*b): #设定可变参数
s = 1
for i in range(1,n+1):
s *= i #计算n!的值
for item in b: #for in,b是一个组合数据类型,包含一个或多个数,每次取一个数,与s相乘
s *= item
return (s)
a = fact(10,3) #10!乘以3
print(a) #结果为10886400
b = fact(10,3,5,8)
print(b) #结果为435456000
例:计算任意输入数的乘积
def cmul(a,*b):
s = a
for i in b:
s *= i
return s
print(eval("cmul({})".format(input())))
参数传递的方式:函数调用时,可以按照位置或名称方式传递。
def fact(n,m=1):
s = 1
for i in range(1,n+1):
s *= i
return s//m
a = fact(10,5) #位置传递
print(a)
b = fact(m=5,n=10) #名称传递
print(b)
函数的返回值:return保留字用来传递返回值,return可以传递1个或多个返回值,之间用,隔开不用加括号!函数可以有返回值,也可以没有,可以有return,也可以没有return。
def fact(n,m=1):
s = 1
for i in range(1,n+1): #不能用range(n),若从0开始,阶乘都为0
s *= i
return s//m,n,m
print(fact(10,5))
a,b,c = fact(10,5) #还可以使用变量,之间用逗号分隔并获得返回值。将函数运算的返回值分别赋给a,b,c
print(a,b,c)
(725760, 10, 5) #元组类型,小括号中间用逗号分隔的几个元素 725760 10 5
局部变量和全局变量:函数体内部的变量为局部变量,函数体外的变量为全局变量。
规则1:局部变量和全局变量是不同的变量,即使重名(基本数据类型)。因为局部变量只是函数内部的占位符,函数运算结束后,局部变量会被释放,就不存在了;可以使用global保留字在函数内部使用全局变量
n,s = 10,100
def fact(n,s):
s = 1
for i in range(1,n+1):
s *= i
return s
print(fact(n,s),s)
#结果为3628800 100 ,s为全局变量中的s,局部变量的s在执行函数后会被释放
n,s = 10,100
def fact(n):
global s #global保留字声明,此处的s是全局变量
for i in range(1,n+1):
s *= i
return s #此处s指全局变量
print(fact(n),s) #此处全局变量s被函数修改
#结果为362880000 362880000
规则2:局部变量为组合数据类型,且未创建时,等同于全局变量。
组合数据类型在python中是由指针体现,如果函数中没有真实创建组合数据类型,它使用的变量是指针,而指针指的是外部的全局变量,所以修改指针对应的内容就修改了全局变量。
ls = ['F','f'] #通过[]创建全局变量列表
def func(a):
ls.append(a) #此处ls为列表类型,未真实创建,则等同于全局变量
return
func('C') #全局变量ls被修改
print(ls)
#结果为['F', 'f', 'C']
ls = ['F','f']
def func(a):
ls = [] #ls为局部变量,函数运行后会被释放,就不存在了
ls.append(a)
return
func('C') #局部变量ls被修改
print(ls)
#结果为['F', 'f']
lambda函数:是一种匿名函数(没有名字的函数),用lambda保留字定义,函数名是返回结果。用于定义简单的、能在一行内表示的函数。谨慎使用lambda函数!
实例7:七段数码管绘制(七段小的数码管,可形成0-9,A-F)
基本思路:绘制单个数字对应的数码管;获得一串数字,绘制对应的数码管;获得当前系统时间,绘制对应的数码管。
已定义函数drawLine(draw),一般调用函数是给定实参。但如果是drawLine(True)就可以执行前面的函数。drawLine(True)不执行函数drawLine。
import turtle
def drawLine(draw): #绘制一条线
turtle.pendown() if draw else turtle.penup() #如果参数是draw就落笔,否则起飞
turtle.fd(40)
turtle.right(90)
#如果是drawLine(True)是不是就可以执行函数呢?是的
def drawDigit(digit): #绘制一个数字
drawLine(True) if digit in [2,3,4,5,6,8,9] else drawLine(False) #如果参数在[]中,True,执行drawLine函数,否则不执行
drawLine(True) if digit in [0,1,3,4,5,6,7,8,9] else drawLine(False)
drawLine(True) if digit in [0,2,3,5,6,8,9] else drawLine(False)
drawLine(True) if digit in [0,2,6,8] else drawLine(False)
turtle.left(90) #在drawLine函数中有turtle.right(90),每画一次都会拐个弯
drawLine(True) if digit in [0,4,5,6,8,9] else drawLine(False)
drawLine(True) if digit in [0,2,3,5,6,7,8,9] else drawLine(False)
drawLine(True) if digit in [0,1,2,3,4,7,8,9] else drawLine(False)
turtle.left(180)
turtle.penup() #为绘制后续数字确定位置
turtle.fd(20)
def drawDate(date): #绘制一串数字
for i in date:
drawDigit(eval(i))
def main():
turtle.setup(800,350,200,200)
turtle.penup()
turtle.fd(-300)
turtle.pensize(5)
drawDate('20181010')
turtle.hideturtle()
turtle.done()
main()
增加小数码管的间隔,用time库获取系统当前时间,增加年月日的标记,年月日颜色不同
import turtle,time
def drawGap(): #绘制数码管间隔
turtle.penup()
turtle.fd(5)
def drawLine(draw): #绘制小段数码管
drawGap() #调用drawGap函数,绘制数码管间隔
turtle.pendown() if draw else turtle.penup() #如果参数是draw就落笔,否则起飞
turtle.fd(40)
drawGap()
turtle.right(90)
#如果是drawLine(True)是不是就可以执行函数呢?是的
def drawDigit(digit): #根据数字绘制七段数码管
drawLine(True) if digit in [2,3,4,5,6,8,9] else drawLine(False) #如果参数在[]中,True,执行drawLine函数,否则不执行
drawLine(True) if digit in [0,1,3,4,5,6,7,8,9] else drawLine(False)
drawLine(True) if digit in [0,2,3,5,6,8,9] else drawLine(False)
drawLine(True) if digit in [0,2,6,8] else drawLine(False)
turtle.left(90) #在drawLine函数中有turtle.right(90),每画一次都会拐个弯
drawLine(True) if digit in [0,4,5,6,8,9] else drawLine(False)
drawLine(True) if digit in [0,2,3,5,6,7,8,9] else drawLine(False)
drawLine(True) if digit in [0,1,2,3,4,7,8,9] else drawLine(False)
turtle.left(180)
turtle.penup() #为绘制后续数字确定位置
turtle.fd(20)
def drawDate(date): #data为日期,格式为 '%Y-%m=%d+'
turtle.pencolor("red")
for i in date:
if i == '-':
turtle.write("年",font=("Arial",18,"normal")) #用turtle.write()写汉字,先字体再字号
turtle.pencolor("green") #在'-'后面的颜色变为绿色
turtle.fd(40)
elif i == '=':
turtle.write("月",font=("Arial",18,"normal"))
turtle.pencolor("blue")
turtle.fd(40)
elif i == '+':
turtle.write("日",font=("Arial",18,"normal"))
else:
drawDigit(eval(i)) #注意要用eval()去掉最外面的引号
def main():
turtle.setup(800,350,200,200)
turtle.penup()
turtle.fd(-300)
turtle.pensize(5)
drawDate(time.strftime('%Y-%m=%d+',time.gmtime())) #获取当前时间,并转为计算机程序可处理的时间格式
turtle.hideturtle()
turtle.done()
main()
举一反三:理解方法思维,模块化思维:确定模块接口,封装功能;规则化思维:抽象过程为规则,计算机自动执行(每个数字都走了7条线,用参数控制是绘 制/飞过去不绘制);化繁为简:将大功能变为小功能组合。应用问题拓展:带小数点的七段数码管、带刷新的时间倒计时效果。
代码复用的两种形式:函数和对象。函数将代码命名,在代码层面建立了初步抽象;对象通过属性和方法. 和 .(),在函数之上再次组织进行抽象,抽象级别变高。
模块化设计:通过函数或对象,封装,将程序划分为模块及模块间的表达。具体包括:主程序、子程序和子程序间关系。模块化设计要求紧耦合、松耦合:模块内部紧耦合、模块之间松耦合(模块内通过局部变量进行大量传输,函数间尽可能减少传递参数和返回值,才能使代码尽可能复用)。
递归:一个函数调用自己。函数+分支结构(if + else),分支结构判断递归链条和递归基例(一个或多个不需再次递归)。递归在数学中的高大上表达:数学归纳法.
递归的调用过程:把函数的定义理解为一个模板,计算机对赋予的参数去运算时,会将函数的模板拷贝一份,放到计算机的某一个位置,用实际给定的参数去运算;若运算过程中又遇到一个函数,会在计算机中再开辟一个新内存,再运算。这样就可以不断调用程序自身。函数定义的过程调用的是自身,但函数执行的过程调用的是不同自身代码的复制版本。
def fact(n):
if n == 0:
return 1
else:
return n*fact(n-1)
print(fact(5)) #结果为120
实例1:字符串反转后输出
>>>s[::-1] :字符串s从最开始到最后采用-1的步长进行输出,-1的步长就是指从后向前依次取出
分析:函数+分支结构(链条,基例),基例:空字符串,链条:将首字符放到其余字符最后
def rvs(s):
if s == "":
return s
else:
return rvs(s[1:])+s[0]
实例2:斐波那契数列
def f(n):
if n == 1 or n == 2:
return 1
else:
return f(n-1)+f(n-2)
实例3:汉诺塔问题(递归的经典案例)若干不同颜色不同大小的圆圈,3根柱子,每次移动一个盘子,但要使得3个柱子都是从小到大排列。
递归链条的分析:将n个圆盘从A柱搬到C柱:先将n-1个圆盘从A搬到B,将最后一个圆盘搬到C;再将B柱中的n-1个圆盘挪到C柱上。总之:把n个圆盘化解为n-1个圆盘的搬运,n-1个圆盘怎么搬呢?递归过程只关系递归链条,只关心当圆盘数量为n时,怎么拆解为当前与当前n-1之间的关系。
def move(start,target):
print("{} -> {}".format(start,target))
def hanoi(n,first,second,third): #first为源柱,second为帮助柱,third为目标住
if n == 1:
move(first,third)
else:
hanoi(n-1,first,third,second)#位置函数,把first上的n-1个盘子移动到second
hanoi(1,first,second,third) #把first上剩下的1个盘子移动到third
hanoi(n-1,second,first,third) #把second上的n-1个盘子移动到third
hanoi(3,"A","B","C")
位置函数:函数的参数是由位置决定的 。注:后面else中的递归hanoi的参数位置与函数定义hanoi的参数位置有关。
count = 0
def hanoi(n,src,dst,mid): #有n个圆盘,3根柱子:源柱子,目的柱子,中间过渡柱子
global count #为了计算每一次移动圆盘的步骤,定义全局变量,递归函数本身也是函数,若内部变量不是全局变量,再每次调用时初值都是被清零
if n == 1:
print("{}:{}->{}".format(1,src,dst))
count += 1 #每次移动圆盘时对全局变量加一
else:
hanoi(n-1,src,mid,dst) #位置函数,把n-1个圆盘搬到中间柱子上 src---mid
print("{}:{}->{}".format(n,src,dst)) #将搬运过程打印出来
count += 1
hanoi(n-1,mid,dst,src)#将n-1个圆盘从之前的中间柱子搬运到目标柱子上 mid---dst
hanoi(3,"A","C","B")
print(count)
1:A->C 2:A->B 1:C->B 3:A->C 1:B->A 2:B->C 1:A->C 7
PyInstaller库:第三方库,将扩展名为.py的源代码转换成无需源代码的可执行文件,系统上可能没有安装python的IDLE或者解释器,将源程序先编译或者打包成一个可以直接执行的程序。
PyInstaller是命令行的执行程序,不是python执行指令。以七段数码管为例(SevenDigitDraw),打开cmd,在源代码目录下, pyinstaller -F<文件名.py> ,生成3个新的目录:__pycache__和build可删除,dist文件中有一个与原文件同名的exe文件,鼠标双击,执行程序。
PyInstaller库常用参数:例:对一个源代码文件关联一个图标(curve.ico),并进行打包。pyinstaller -i curve.ico -F SevenDigitsDrawV2.py,会产生一个包含预定图标的可执行文件。
注:只有在打包过程的计算机中,需安装PyInstaller库,打包后的程序(.exe)发给朋友可直接执行
实例8 科赫雪花小包裹
分形几何:整体与局部具有很强的相似性,分形几何中有一种特殊的曲线:科赫曲线(雪花曲线)
分析:递归思想:函数+分支 递归链条:线段的组合 递归基例:初识线段
#绘制科赫曲线
import turtle
def koch(size,n): #线段长度size,阶数n
if n == 0:
turtle.fd(size) #绘制一条直线,不需要return
else: #将一条直线分为3段,中间段去掉,再进一阶:把其中每一个线段做下一次科赫曲线绘制
for angle in [0,60,-120,60]:
turtle.left(angle)
koch(size/3,n-1) #!为n-1
def main():
turtle.setup(800,400)
turtle.penup()
turtle.goto(-300,-50)
turtle.pendown()
turtle.pensize(2)
koch(600,3) #3阶科赫曲线
turtle.hideturtle() #将海龟本身进行隐藏
main()
#绘制科赫小雪花
import turtle
def koch(size,n): #线段长度size,阶数n
if n == 0: #基例 n为0,而非1
turtle.fd(size) #绘制一条直线
else: #将一条直线分为3段,中间段去掉,再进一阶:把其中每一个线段做下一次科赫曲线绘制
for angle in [0,60,-120,60]:
turtle.left(angle)
koch(size/3,n-1)
def main():
turtle.setup(600,600)
turtle.penup()
turtle.goto(-200,100)
turtle.pendown()
turtle.pensize(2)
level = 3 #3阶科赫雪花
koch(400,level)
turtle.right(120)
koch(400,level)
turtle.right(120) #若绘制的不是科赫曲线,则是等边三角形
koch(400,level)
turtle.hideturtle() #将海龟本身进行隐藏
main()
举一反三:修改绘制阶数、修改科赫曲线旋转角度、修改科赫雪花的基础框架图形;康托尔集、谢尔宾斯基三角形、门格海绵…龙形曲线、空间填充曲线、科赫曲线等分形几何
组合数据类型包括:集合类型、序列类型、字典类型
集合类型:元素无序,每个元素唯一,不存在相同类型;元素不可更改,不可变数据类型。(因为集合中元素是独一无二,若改变后可能会与其他元素相同)集合用大括号{ }表示,元素间用逗号分隔;建立集合类型用{ }或set( );建立空集合,必须用set( )
>>> ls = set("123") #使用set()函数创建集合类型,要在()中添加“”,不需要间隔,其中的,也会当作元素
{'2', '1', '3'}
>>> ls = set("1,2,3")
{',', '1', '3', '2'}
>>> B = set("pypy123") #使用set()建立集合
{'3', 'y', 'p', '1', '2'} #把相同的元素删除,元素不是按定义的顺序,因为集合无序
>>> A = {"python",123,("python",123)} #使用{}建立集合
{('python', 123), 123, 'python'}
>>> C = {"python",123,"python",123}
{123, 'python'}
集合操作符:
>>> A = {"p","y",123}
>>> B = set("pypy123")
>>> A - B
{123}
>>> B - A
{'3', '1', '2'}
>>> A&B
{'p', 'y'}
>>> A|B
{'3', 'y', 'p', '1', 123, '2'}
>>> A^B
{'3', '1', '2', 123}
集合类型处理函数+方法:(方法=变量+“.”称为.xxx方法)10个
>>> A = {"p","y",123}
>>> for item in A:
print(item,end="")
123yp
>>> A
{123, 'y', 'p'}
A = {"p","y",123}
try:
while True: #程序不断运行,看似形成了一个死循环
print(A.pop(),end="") #但A中元素不存在时,会产生异常,会被try-except捕捉到,正常退出
except:
pass
123yp
>>>A
set() #程序运行结束后,A为空集合
注:使用for in 循环,返回获得的元素也不确定,可能与定义的顺序不同。(其实一个集合类型定义生成后,内部是有顺序的,但这个顺序对于程序员来讲,是无法利用的,是程序内部保存集合时所运用的一种顺序)
集合类型的应用场景:包含关系比较,比较一组数据是否在这个数据中;数据去重,集合类型所有元素无重复
>>>"p" in {"p","y",123}
True
>>>{"p","y"} >= {"p","y",123}
False
>>>ls = ["p","p","y","y",123]
>>>s = set(ls) #set()函数,将列表转为集合(也可逐一比较判断是否相同,但太复杂)
{123, 'y', 'p'}
>>>lt = list(s) #list()函数,可将集合类型转为列表类型
[123, 'y', 'p']
序列类型 :是一组有先后关系的元素,元素间由序号引导,通过下标访问序列的特定元素,可正向/反向递增/减序号。序列是一个基类类型,包括字符串类型、元组类型、列表类型。
序列类型的操作符、函数和方法
ls = ["python",123,".io"] ls[::-1] Out[13]: ['.io', 123, 'python'] s = "python123.io" s[::-1] Out[15]: 'oi.321nohtyp'
ls = ["python",123,".io"] len(ls) Out[17]: 3 s = "python123.io" max(s) #获得序列中最大的元素,字符串序列中,每个元素都是字符,字符间的比较是按照字母序比较 Out[19]: 'y'
元组类型:是一种序列类型,一旦创建不能修改;用小括号()/tuple()创建,元素间用逗号分隔,可用或不用小括号。 如def func(): ;return 1,2 返回的1,2就是一个元组
>>>creature = "cat","dog","tiger","human" #元组可以没有括号
>>>creature
('cat', 'dog', 'tiger', 'human')
>>>creature[::-1] #新创建一个元组
('human', 'tiger', 'dog', 'cat')
>>>color = (0x001100,"blue",creature)
>>>color
(4352, 'blue', ('cat', 'dog', 'tiger', 'human'))
>>>color[-1][2] #元组color的[-1]是creature元组,creature元组[2]是tiger
'tiger'
列表类型:是一种序列类型,创建后能随意修改;用方括号[ ]/list()创建,元素间用逗号分隔,列表中元素类型可不同,无长度限制。如果使用[]或list,真正创建了一个列表,若仅使用=赋值,它只是将一段列表赋给了一个新的名字,相当于重命名
列表类型的函数或方法
列表中的函数/方法会作用到列表本身,删除列表元素:del ls[i]、 ls.pop(i)、 ls.remove(x)。
>>> ls = ["cat","dog","tiger",1024] >>> ls[1:2] = [1,2,3,4] ['cat', 1, 2, 3, 4, 'tiger', 1024] >>> del ls[::3] #删除步长为3的元素,即删除0、3、6 [1, 2, 4, 'tiger'] >>> ls * 2 #列表中的函数/方法会作用到列表本身 [1, 2, 4, 'tiger', 1, 2, 4, 'tiger']
>>> ls = ["cat","dog","tiger",1024] >>> ls.append(1234) ['cat', 'dog', 'tiger', 1024, 1234] >>> ls.insert(3,"human") ['cat', 'dog', 'tiger', 'human', 1024, 1234] >>> ls.reverse() [1234, 1024, 'human', 'tiger', 'dog', 'cat']
列表功能默写
序列类型应用场景:元组tp用于元素不改变的应用场景,如函数return;列表ls更灵活,使最常用的序列类型。主要作用:表示一组有序数据,进而操作它们。元素遍历:for item in ls:;<语句块>、or item in tp:;<语句块>。 数据保护:不希望数据被程序所改变,转换为元组类型
>>> ls = ["cat","dog","tiger",1024]
>>> lt = tuple(ls) #定义为元组类型
>>> lt
('cat', 'dog', 'tiger', 1024)
实例9:“基本统计值计算”问题:求和、平均值、方差、中位数
给出一组数据,求总个数:len()、求和:for…in、平均值:求和/总个数、方差:各数据与平均数差的平方的和的平均数、中位数:排序,奇数找中间1个,偶数找中间2个取平均。
与pandas数据的.describle()方法效果类似,注:print的槽机制.format( )中可以直接调用函数。sorted()函数和.sort方法可以对列表进行排序
def getNum(): #获得用户不定长度的输入
nums = []
iNumStr = input("请输入数字(回车退出):")
while iNumStr != "":
nums.append(eval(iNumStr))
iNumStr = input("请输入数字(回车退出):")
return nums
def mean(numbers): #计算平均数
s = 0.0
for num in numbers:
s += num
return s / len(numbers)
def dev(numbers,mean): #计算方差
sdev = 0.0
for num in numbers:
sdev = sdev + (num - mean)**2
return pow(sdev / (len(numbers)-1),0.5)
def median(numbers): #计算中位数
sorted(numbers) #sorted函数可以对列表进行排序,计算中位数要先排序
size = len(numbers)
if size % 2 == 0: #这里要用%,判断有没有余数来判断奇偶个数,后面要用//
med = (numbers[size//2-1] + numbers[size//2])/2 #要注意numbers[]是从0开始的,在找中位数时要注意位置
else:
med = numbers[size//2] #//整数除法,即商
return med
n = getNum()
m = mean(n)
print("平均值:{},方差:{:.2},中位数:{}".format(m,dev(n,m),median(n)))
请输入数字(回车退出):1 请输入数字(回车退出):2 请输入数字(回车退出):3 请输入数字(回车退出):4 请输入数字(回车退出):5 请输入数字(回车退出):6 请输入数字(回车退出):7 请输入数字(回车退出):8 请输入数字(回车退出):9 请输入数字(回车退出): 平均值:5.0,方差:2.7,中位数:5
举一反三:从控制台获取多个不确定数据数据(while),模块化设计方法(分隔多个函数),充分利用python提供的内容函数(排序:sorted函数,个数:len函数,平方根/开平方:pow函数)
理解“映射”:是一种键和值的对应,序列类型由0…N整数作为数据的默认索引(["python",123,".io"]),映射类型由用户为数据自定义索引(内部颜色:蓝色),数据组织与表达的新的形态,字典类型是“映射”的体现。
字典:键值对的集合,键值对之间无序,键是数据索引的扩展;采用大括号{}和dict创建,键值对用:表示,元素间用,分隔,字典变量= {<键1>:<值1>,<键2>:<值2>,…<键3>:<值3>}
<值>=<字典变量> [键] <字典变量>[键]=<值> ,d[key]用来向字典变量中索引或增加元素。
在集合类型中,生成空集合不能用空{}的方式只能用set()函数,因为空{}默认生成字典类型。函数type(x):返回变量x的类型。创建字典时,若相同键有不同值,字典采用最后一个"键值对"。
>>> d = {"中国":"北京","美国":"华盛顿","法国":"巴黎"}
>>> d["中国"]
'北京'
>>> de = {};type(de)
字典类型的函数或方法
注:方法.keys()和.values()和.items( )不返回列表类型,返回字典的key类型或values类型,可用for in 的方式做遍历,但不能当列表类型来操作。如 for nation,capital in d.items() 遍历字典中的每一个键值对,并赋值给键和值的变量nation,capital。如果只用for i in d:只会返回键(国家)
.get( )方法很重要,判断键是否在字典中,返回值!若要增加键值对,直接字典名["键"] = "值"
字典转为列表时,一定要记得用方法.items()
>>> d = {"中国":"北京","美国":"华盛顿","法国":"巴黎"}
>>> "中国" in d
True
>>> d.keys()
dict_keys(['中国', '美国', '法国'])
>>> d.values()
dict_values(['北京', '华盛顿', '巴黎'])
>>>d["韩国"] = "首尔"
{'中国': '北京', '美国': '华盛顿', '法国': '巴黎', '韩国': '首尔'}
>>>d.items()
dict_items([('中国', '北京'), ('美国', '华盛顿'), ('法国', '巴黎'), ('韩国', '首尔')])
>>>list(d)
['中国', '美国', '法国', '韩国']
>>> list(d.items())
[('中国', '北京'), ('美国', '华盛顿'), ('法国', '巴黎'), ('韩国', '首尔')]
>>> d = {"中国":"北京","美国":"华盛顿","法国":"巴黎"}
>>> d.get("中国","伊斯兰堡") #以中国为键,获得d中对应的值,若不是字典d中的索引就返回伊斯兰堡
'北京'
>>> d.get("巴基斯坦","伊斯兰堡")
'伊斯兰堡'
>>> d.popitem() #从字典d中随机获取一个键值对,以元组形式表达
('法国', '巴黎')
字典类型应用场景:映射的表达,如统计数据出现的次数,数据为键,次数是值。元素遍历:for k in d: <语句块>
读入一个字典类型的字符串,反转其中键值对输出
示例{"a": 1, "b": 2},输出{1: 'a', 2: 'b'}
s = input()
try:
d = eval(s)
e = {}
for k in d: #字典的单纯遍历,只会返回字典的键,即k=a,b
e[d[k]] = k
print(e)
except:
print("输入错误")
jieba库:优秀的中文分词第三方库,中文文本需要通过分词获得单个的词语(确定中文字符之间的关联概率,概率大的组成词组形成分词结果,用户可自定义添加词组);需额外安装(在cmd命令行输入pip install jieba,需在联网状态);提供三种分词模式,最简单只需掌握一个函数。
精确模式:把文本精确切分开,不存在冗余单词。最常用
全模式:把文本中所有可能的词语都扫描出来,有冗余。不同的角度来切分,变成不同的词语
搜索引擎模式:在精确模式基础上,对长词再次切分。更智能
jieba库常用函数 jieba.lcut(s)
实例10:文本词频统计
英文文本:Hamet 分析词频 https://python123.io/resources/pye/hamlet.txt
中文文本:《三国演义》分析人物出场次数 https://python123.io/resources/pye/threekingdoms.txt
1、文本噪音处理、归一化,大小写、单词间的:,!等符号.replace,.split方法分隔为列表words
2、建立空字典counts,单词和频次的映射,for in循环 + 字典的.get()方法获得所有单词及频次
3、转为列表items,sort函数的高级用法进行词频排序,for in循环输出前几的单词及词频
open("hamlet.txt","r").read() #打开Hamlet文件+.read()方法
items.sort(key=lambda x:x[1],reverse=True) #用.sort()方法进行排序,lambda函数:lambda +参数 + :+ 函数体,用于定义简单的、能在一行内表示的函数,该代码中用来指定列表中使用哪一个多元选项的列作为排序列;默认排序为从小到大,reverse=True返回的排序为从大到小。
for word in words: counts[word] = counts.get(word,0) + 1 #相当于新增键值对, 若返回word,返回的是word键对应的值。
print("{0:<10}{1:>5}".format(word,count)) #:后面数字---输出宽度,出现.---精度,出现,---千位分隔符,出现><^---对齐,出现字母---类型。
counts = { }
counts['fortune'] = counts.get('fortune',0) + 1 = 1 counts = { 'fortune':1}
counts['the'] = counts.get('the',0) + 1 = 1 counts = { 'fortune':1,'the':1}
counts['the'] = counts.get('the',0) + 1 = 1+1=2 counts = { 'fortune':1,'the':2}
words = ['fortune','the','who','who','the','are','the']
counts = {}
for word in words:
counts[word] = counts.get(word,0) + 1
print(counts)
{'fortune': 1, 'the': 3, 'who': 2, 'are': 1}
def getText(): #归一化处理
txt = open("hamlet.txt","r").read() #打开文件的方法 open("","r").read()
txt = txt.lower() #将所有英文字符变成小写
for ch in '!"$%&()*+,-./:;<=>?@[\]^_{|}~': #for in的方式去掉文本中各种特殊符号
txt = txt.replace(ch,"") #用replace方法将特殊符号替换为空格
return txt
hamletTxt = getText()
words = hamletTxt.split() #.split方法默认用空格对字符串进行分隔,并以列表的形式返回变量,里边的每个元素就是空格分开的单词
counts = {} #单词与出现次数——映射,构建字典类型
for word in words:
counts[word] = counts.get(word,0) + 1 #判断元素word(键)是否在counts中,字典的.get()方法获得键对应的值/给出默认值,在里边返回次数+1,若不在字典中就加到字典中并赋值为0
items = list(counts.items()) #将字典类型转为列表类型便于操作,.items()方法返回字典中所有的键值对
items.sort(key=lambda x:x[1],reverse=True) #用.sort()方法进行排序,lambda函数
for i in range (10):
word,count = items[i]
print("{0:<10}{1:>5}".format(word,count))
the 1137 and 963 to 736 of 669 you 546 i 540 a 527 my 513 hamlet 459 in 435
word,count = items[i],注意是列表中的一个元素返回两个值,而不是字典
《三国演义》人物出场统计(上)将词频与人物相关联,面向问题
import jieba
txt = open('threekingdoms.txt','r',encoding='utf-8').read()
words = jieba.lcut(txt) #分词处理,形成带所有单词的列表类型,jieba库可以不用删除特殊符号
counts = {}
for word in words:
if len(word) == 1:
continue #结束循环,如果是单个的词就结束本轮循环,如曰,吾,也,标点符号等
else:
counts[word] = counts.get(word,0) + 1
items = list(counts.items()) #一定要记得字典转为列表时,要用方法.items()
items.sort(key = lambda x:x[1],reverse = True)
for i in range(15):
word,count = items[i]
print("{0:<10}{1:>5}".format(word,count))
曹操 953 孔明 836 将军 772 却说 656 玄德 585 关公 510 丞相 491 二人 469 不可 440 荆州 425 玄德曰 390 孔明曰 390 不能 384 如此 378 张飞 358
但结果中“孔明”和“孔明曰”实际上是一个人,只是由于分词的原因,将其做为两个不同的单词;“二人”和“却说”不是人名而是单词的组合,要给出排除词库
《三国演义》人物出场统计(下)
import jieba
txt = open('threekingdoms.txt','r',encoding='utf-8').read()
excludes = {"将军","却说","荆州","二人","不可","不能","如此"} #确定不是人名,排序靠前的单词列进去,不断运行程序根据结果
words = jieba.lcut(txt)
counts = {}
for word in words:
if len(word) == 1:
continue
elif word == '诸葛亮' or word == '孔明曰': #人名的关联
rword = '孔明'
elif word == '关公' or word == '云长':
rword = '关羽'
elif word == '玄德' or word == '玄德曰':
rword = '刘备'
elif word == '孟德' or word == '丞相':
rword = '曹操'
else:
rword = word
counts[rword] = counts.get(rword,0) + 1
for word in excludes:
del counts[word]
items = list(counts.items())
items.sort(key=lambda x:x[1],reverse=True)
for i in range(10):
word,count = items[i]
print("{0:<10}{1:>5}".format(word,count))
曹操 1451 孔明 1383 刘备 1252 关羽 784 张飞 358 商议 344 如何 338 主公 331 军士 317 吕布 300
文本词频统计举一反三:其他书籍,对政府工作报告、科研论文、新闻报道…进一步,绘制词云有更直观的展示效果
文件:是数据的抽象和集合,文件的展示形态有:文本文件和二进制文件。
文本文件:数据是由单一特定编码组成的,如UTF-8编码;由于存在编码,文本文件也被看成是存储着的长字符串(文本文件就是一个字符串),如txt文件、py文件
二进制文件:由0和1按特定方式组织,没有统一的字符编码,如png图片文件、avi视频文件。任何类型的文件都可以以二进制方式打开。
)
文件处理的步骤:打开---操作---关闭
打开:a = open( , ) 文件从存储状态转为占用状态 关闭:a.close( )文件从占用状态转为存储状态
操作:1.读文件 a.read(size) a.readline(size) a.readlines(hint) 2.写文件 a.write(s) a.writelines(lines) a.seek(offset)
文件的打开:
文件的关闭:
<变量名>.close( ),若程序中只有打开文件,没有调用close()关闭文件,程序运行过程中,文件始终都是打开状态,但当程序退出,python的解释器会自动关闭文件。
文件内容的读取:
方法1:.read()读入全部信息,变成一个大的字符串,采用字符串的处理方法,直接, 但若文本文件体量很大,一次性将文件读入内存,会耗费很多时间和资源。方法2:.read(2)从文件中读入2个字节,对字节进行相关处理,只要读进来的信息不为空,就将持续处理下去,直到为空最后退出。对于分行存储的文件,逐行遍历:方法3:.readlines()为列表,列表中的每一个元素是一行。方法4:逐行读出大文件中的信息 for in 文件句柄
数据的文件写入:
fo = open("output.txt","w+")
ls = ["中国","法国","美国"]
fo.writelines(ls)
fo.seek(0)
for line in fo:
print(line)
fo.close()
>>>中国法国美国
实例11:自动轨迹绘制
问题分析:需要根据脚本来绘制图形,不是写代码而是写数据绘制轨迹。之前用turtle库绘制图形是通过程序写代码的方式绘制图形。而是写程序去读取数据,并根据数据来绘制轨迹。数据脚本是自动化最重要的第一步。要程序能自动化或模块化,设计相关的脚本或数据接口是很重要的过程。
基本思路:定义数据文件格式(接口)程序与数据之间的一种规范 —— 编写程序,根据文件接口解析参数绘制图形 —— 编制数据文件。数据接口定义非常具有个性色彩!
map函数是python的内嵌函数,作用是将第一个参数的功能作用于第二个参数的每一个元素。对一个列表或一个集合这种组合数据类型的每一个元素都执行一次第一个参数所对应的函数。map函数返回的数据类型是
txt = open("001.txt","r")
for line in txt:
line = line.replace("n","")
line = list(map(eval,line.split(",")))
print(line)
#1,2,3,4,5 for in 后直接print(line)会有空行
#6,7,8,9,10
#1,2,3,4,5 for in 后,.replace("n","")用空格代替换行符,print(line)
#6,7,8,9,10
#['1', '2', '3', '4', '5'] for in 后,.replace("n",""),再用.split(",")将字符串分隔形成列表,print(line)
#['6', '7', '8', '9', '10'] 注意:因为是for循环,逐行遍历,所以每一行都会形成一个列表
#[1, 2, 3, 4, 5]
#[6, 7, 8, 9, 10]
#
import turtle as t
t.title('自动轨迹绘制')
t.setup(800,600,0,0)
t.pencolor("red")
t.pensize(5)
#数据读取
datals = [] #用列表存储读取的数据,列表中的每个元素都是一个小列表
f = open("data.txt")
for line in f: #for in 文件句柄,形成列表,每个元素为每一行
line = line.replace("n","") #将换行符转换为空字符串,去掉换行
datals.append(list(map(eval,line.split(",")))) #将一个字符串分隔成若干个字符串生成一个列表,map函数是python提供的内嵌函数,无需import可直接使用,作用是将第一个参数的功能作用于第二个参数的每一个元素
f.close()
#自动绘制
for i in range(len(datals)):
t.pencolor(datals[i][3],datals[i][4],datals[i][5]) #datals[i][3]指获得当前datals的一个元素,并找到元素的第三个参数
t.fd(datals[i][0]) #获取当前这一行中的第一个元素,表示行进距离,赋值给fd
if datals[i][1]: #如果datals[i][1]不等于0(是1),向右转,转向角度都是datals[i][2]
t.right(datals[i][2])
else:
t.left(datals[i][2])
在python中若不知道变量是什么数据类型,可以用print(type(<变量>)),如print(type(line)),会显示
if语句后直接加变量,而不是布尔什表达式:判断该变量是否为非空非0,如果不为空不为0,则返回True,否则返回False。不为0返回else,为0返回if后面的语句
a = 0
if a:
print("123")
else:
print("456")
>>>456
a = "I love you!"
if a:
print("123")
else:
print("456")
>>>123



