简述
掌握函数的基本使用方法,理解并掌握递归使用,掌握PyInstaller库,能够编写带有函数的程序,并能够打包可执行文件。
课件
代码汇总
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: # 37.78 是一年每天努力 1% 的结果
dayfactor += 0.001
print("工作日的努力参数是:{:.3f} ".format(dayfactor))
# 工作日的努力参数是:0.019
def fact(n):
s = 1
for i in range(1, n + 1):
s *= i
return s
a = fact(10)
print(a) # 3628800
def fact(n, m=1): # 可选参数、参数默认值
s = 1
for i in range(1, n + 1):
s *= i
return s // m
print(fact(10)) # 3628800
print(fact(10, 5)) # 725760
def fact(n, *b): # 可变参数
s = 1
for i in range(1, n + 1):
s *= i
for item in b:
s *= item
return s
print(fact(10, 3)) # 10886400
print(fact(10, 3, 5, 8)) # 435456000
def fact(n, m=1):
s = 1
for i in range(1, n + 1):
s *= i
return s // m
# 传参:位置传递
print(fact(10, 5)) # 725760
# 传参:名称传递
print(fact(m=5, n=10)) # 725760
def fact(n, m=1):
s = 1
for i in range(1, n + 1):
s *= i
return s // m, n, m # 返回多个结果
print(fact(10, 5)) # (725760, 10, 5)
# 返回结果 (725760, 10, 5) 是一个 元组类型
# 定义变量接收返回结果
a, b, c = fact(10, 5)
print(a, b, c) # 725760 10 5
n, s = 10, 100 # n 和 s 是全局变量
def fact(n): # fact() 函数中的 n 和 s 是局部变量
s = 1
for i in range(1, n + 1):
s *= i
return s
# 访问到的是全局变量 n 10 s 100
print(fact(n), s) # 3628800 100
n, s = 10, 100
def fact(n):
# s = 1 # 局部变量
global s # 使用全局变量 s
for i in range(1, n + 1):
s *= i
return s
print(fact(n), s) # 362880000 362880000
ls = ["F", "f"]
def func(a):
ls.append(a)
return
func("C")
print(ls) # ['F', 'f', 'C']
ls = ["F", "f"]
def func(a):
ls = []
ls.append(a)
print(ls) # ['C']
return
func("C")
print(ls) # ['F', 'f']
f = lambda x, y: x + y
print(f(10, 15)) # 25
f = lambda: "lambda函数"
print(f()) # lambda函数
import turtle
def drawLine(draw): # 绘制单段数码管
turtle.pendown() if draw else turtle.penup()
turtle.fd(40)
turtle.right(90)
def drawDigit(digit): # 根据数字绘制七段数码管
drawLine(True) if digit in [2, 3, 4, 5, 6, 8, 9] else drawLine(False)
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(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)) # 通过eval()函数将数字变为整数
def main():
turtle.setup(800, 350, 200, 200)
turtle.penup()
turtle.fd(-300)
turtle.pensize(5)
drawDate("20181010")
turtle.hideturtle()
turtle.done()
main()
import turtle, time
def drawGap(): # 绘制数码管间隔
turtle.penup()
turtle.fd(5)
def drawLine(draw): # 绘制单段数码管
drawGap()
turtle.pendown() if draw else turtle.penup()
turtle.fd(40)
drawGap()
turtle.right(90)
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.left(180)
turtle.penup()
turtle.fd(20)
def drawDate(date):
turtle.pencolor("red")
for i in date:
if i == "-":
turtle.write("年", font=("Arial", 18, "normal"))
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))
def main():
turtle.setup(800, 350, 200, 200)
turtle.penup()
turtle.fd(-350)
turtle.pensize(5)
# drawDate('2018-10=10+')
drawDate(time.strftime("%Y-%m=%d+", time.gmtime()))
turtle.hideturtle()
turtle.done()
main()
def fact(n):
if n == 0:
return 1
else:
return n * fact(n - 1)
print(fact(0)) # 1
print(fact(1)) # 1
print(fact(2)) # 2
print(fact(3)) # 6
print(fact(4)) # 24
print(fact(5)) # 120
def rvs(s):
if s == "":
return s
else:
return rvs(s[1:]) + s[0]
# s[::-1]
def f(n):
if n == 1 or n == 2:
return 1
else:
return f(n - 1) + f(n - 2)
count = 0
def hanoi(n, src, dst, mid):
global count
if n == 1:
print("{}:{} -> {}".format(1, src, dst))
count += 1
else:
hanoi(n - 1, src, mid, dst)
print("{}:{} -> {}".format(n, src, dst))
count += 1
hanoi(n - 1, mid, dst, src)
hanoi(3, 'A', 'B', 'C')
'''
1:A -> B
2:A -> C
1:B -> C
3:A -> B
1:C -> A
2:C -> B
1:A -> B
'''
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.penup()
turtle.goto(-300, -50)
turtle.pendown()
turtle.pensize(2)
koch(600, 3) # 0阶科赫曲线长度,阶数
turtle.hideturtle()
turtle.done()
main()
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(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()
turtle.done()
main()
def f(a, b):
a = 4
return a + b
def main():
a = 5
b = 6
print(f(a, b), a + b)
main() # 10 11
def func(a, b):
c = a ** 2 + b
b = a
return c
a = 10
b = 100
c = func(a, b) + a
print(a, b, c) # 10 100 210
def prime(m):
for i in range(2, m):
if m % i == 0:
return False
return True
n = eval(input())
n_ = int(n)
n_ = n_ + 1 if n_ < n else n_
count = 5
while count > 0:
if prime(n_):
if count > 1:
print(n_, end=",")
else:
print(n_, end="")
count -= 1
n_ += 1
"""
12
13,17,19,23,29
"""
def cmul(a, *b):
m = a
for i in b:
m *= i
return m
print(eval("cmul({})".format(input())))
"""
1,2,3,4
24
"""
第 5 周导学
前课复习
.mp4%22%2C%22size%22%3A90144844%2C%22taskId%22%3A%22u017e4acf-21fd-48c3-8a4f-39db410b2ae%22%2C%22taskType%22%3A%22upload%22%2C%22url%22%3Anull%2C%22cover%22%3Anull%2C%22videoId%22%3A%22inputs%2Fprod%2Fyuque%2F2023%2F2331396%2Fmp4%2F1688480390021-10cc712e-a454-480a-813e-e785d50d9717.mp4%22%2C%22download%22%3Afalse%2C%22__spacing%22%3A%22both%22%2C%22id%22%3A%22G7G1H%22%2C%22margin%22%3A%7B%22top%22%3Atrue%2C%22bottom%22%3Atrue%7D%2C%22card%22%3A%22video%22%7D#G7G1H)
本课概要
.mp4%22%2C%22size%22%3A37227294%2C%22taskId%22%3A%22u66ff1154-1024-4601-aef3-ba96235c124%22%2C%22taskType%22%3A%22upload%22%2C%22url%22%3Anull%2C%22cover%22%3Anull%2C%22videoId%22%3A%22inputs%2Fprod%2Fyuque%2F2023%2F2331396%2Fmp4%2F1688480397500-6f0912d4-04ab-4109-8d11-c1179f6e7738.mp4%22%2C%22download%22%3Afalse%2C%22__spacing%22%3A%22both%22%2C%22id%22%3A%22nYMk1%22%2C%22margin%22%3A%7B%22top%22%3Atrue%2C%22bottom%22%3Atrue%7D%2C%22card%22%3A%22video%22%7D#nYMk1)
函数的定义与使用
单元开篇
.mp4%22%2C%22size%22%3A14106042%2C%22taskId%22%3A%22u0a96ae3e-8cb9-426c-baa4-6e5d98d74cf%22%2C%22taskType%22%3A%22upload%22%2C%22url%22%3Anull%2C%22cover%22%3Anull%2C%22videoId%22%3A%22inputs%2Fprod%2Fyuque%2F2023%2F2331396%2Fmp4%2F1688480367029-059a1b72-e61c-48d5-8bb6-332da6cdb0b0.mp4%22%2C%22download%22%3Afalse%2C%22__spacing%22%3A%22both%22%2C%22id%22%3A%22KbRE7%22%2C%22margin%22%3A%7B%22top%22%3Atrue%2C%22bottom%22%3Atrue%7D%2C%22card%22%3A%22video%22%7D#KbRE7)
函数的理解与定义
.mp4%22%2C%22size%22%3A53762333%2C%22taskId%22%3A%22ub01094ba-3ef3-4748-94b1-da875422d05%22%2C%22taskType%22%3A%22upload%22%2C%22url%22%3Anull%2C%22cover%22%3Anull%2C%22videoId%22%3A%22inputs%2Fprod%2Fyuque%2F2023%2F2331396%2Fmp4%2F1688480367030-dc59a76a-8be4-4238-852a-297df5010349.mp4%22%2C%22download%22%3Afalse%2C%22__spacing%22%3A%22both%22%2C%22id%22%3A%22YxIHF%22%2C%22margin%22%3A%7B%22top%22%3Atrue%2C%22bottom%22%3Atrue%7D%2C%22card%22%3A%22video%22%7D#YxIHF)
- 函数是一段具有特定功能的、可重用的语句组
- 函数是一种功能的抽象,一般函数表达特定功能
- 函数的两个主要作用:
- 降低编程难度
- 代码复用
- 函数定义时,所指定的参数是一种占位符
- 函数定义后,如果不经过调用,不会被执行
- 函数定义时,参数是输入、函数体是处理、结果是输出(IPO)
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: # 37.78 是一年每天努力 1% 的结果
dayfactor += 0.001
print("工作日的努力参数是:{:.3f} ".format(dayfactor))
# 工作日的努力参数是:0.019
Python 函数的书写格式:
def fact(n):
s = 1
for i in range(1, n + 1):
s *= i
return s
- 函数名:fact
- 函数参数:n
- 函数返回值:s
函数的使用及调用过程
.mp4%22%2C%22size%22%3A35434263%2C%22taskId%22%3A%22u86453745-1c95-42af-9a45-e6874bb7c96%22%2C%22taskType%22%3A%22upload%22%2C%22url%22%3Anull%2C%22cover%22%3Anull%2C%22videoId%22%3A%22inputs%2Fprod%2Fyuque%2F2023%2F2331396%2Fmp4%2F1688480367046-dad3b13a-9069-4d4f-9d63-43f36bdca499.mp4%22%2C%22download%22%3Afalse%2C%22__spacing%22%3A%22both%22%2C%22id%22%3A%22Ugdw6%22%2C%22margin%22%3A%7B%22top%22%3Atrue%2C%22bottom%22%3Atrue%7D%2C%22card%22%3A%22video%22%7D#Ugdw6) 调用是运行函数代码的方式
函数的调用过程:(图中的箭头是动态一步步生成的,若不清楚函数的调用过程,建议回看视频以了解详细步骤)
def fact(n):
s = 1
for i in range(1, n + 1):
s *= i
return s
a = fact(10)
print(a) # 3628800
函数的参数传递
.mp4%22%2C%22size%22%3A89750489%2C%22taskId%22%3A%22u249239ed-04e9-49bc-b21e-79ef7026d74%22%2C%22taskType%22%3A%22upload%22%2C%22url%22%3Anull%2C%22cover%22%3Anull%2C%22videoId%22%3A%22inputs%2Fprod%2Fyuque%2F2023%2F2331396%2Fmp4%2F1688480367053-1aef95cd-3a39-4249-af24-daffbc2b0aed.mp4%22%2C%22download%22%3Afalse%2C%22__spacing%22%3A%22both%22%2C%22id%22%3A%22IhIEL%22%2C%22margin%22%3A%7B%22top%22%3Atrue%2C%22bottom%22%3Atrue%7D%2C%22card%22%3A%22video%22%7D#IhIEL)
可选参数:
def fact(n, m=1): # 可选参数、参数默认值
s = 1
for i in range(1, n + 1):
s *= i
return s // m
print(fact(10)) # 3628800
print(fact(10, 5)) # 725760
可变参数:
def fact(n, *b): # 可变参数
s = 1
for i in range(1, n + 1):
s *= i
for item in b:
s *= item
return s
print(fact(10, 3)) # 10886400
print(fact(10, 3, 5, 8)) # 435456000
def fact(n, m=1):
s = 1
for i in range(1, n + 1):
s *= i
return s // m
# 传参:位置传递
print(fact(10, 5)) # 725760
# 传参:名称传递
print(fact(m=5, n=10)) # 725760
函数的返回值
.mp4%22%2C%22size%22%3A33471487%2C%22taskId%22%3A%22u6b842606-70e2-4a39-9117-452e63b0f9f%22%2C%22taskType%22%3A%22upload%22%2C%22url%22%3Anull%2C%22cover%22%3Anull%2C%22videoId%22%3A%22inputs%2Fprod%2Fyuque%2F2023%2F2331396%2Fmp4%2F1688480367053-9d6589eb-62ea-4185-b23d-2257624f46c1.mp4%22%2C%22download%22%3Afalse%2C%22__spacing%22%3A%22both%22%2C%22id%22%3A%22PynA4%22%2C%22margin%22%3A%7B%22top%22%3Atrue%2C%22bottom%22%3Atrue%7D%2C%22card%22%3A%22video%22%7D#PynA4)
def fact(n, m=1):
s = 1
for i in range(1, n + 1):
s *= i
return s // m, n, m # 返回多个结果
print(fact(10, 5)) # (725760, 10, 5)
# 返回结果 (725760, 10, 5) 是一个 元组类型
# 定义变量接收返回结果
a, b, c = fact(10, 5)
print(a, b, c) # 725760 10 5
局部变量和全局变量
.mp4%22%2C%22size%22%3A149031881%2C%22taskId%22%3A%22u0da483f9-1e09-404b-aba9-e8bd6fd8e66%22%2C%22taskType%22%3A%22upload%22%2C%22url%22%3Anull%2C%22cover%22%3Anull%2C%22videoId%22%3A%22inputs%2Fprod%2Fyuque%2F2023%2F2331396%2Fmp4%2F1688480377688-c2a6b4d6-0d4f-46ec-a55a-bcfdd4634920.mp4%22%2C%22download%22%3Afalse%2C%22__spacing%22%3A%22both%22%2C%22id%22%3A%22wAyKl%22%2C%22margin%22%3A%7B%22top%22%3Atrue%2C%22bottom%22%3Atrue%7D%2C%22card%22%3A%22video%22%7D#wAyKl)
n, s = 10, 100 # n 和 s 是全局变量
def fact(n): # fact() 函数中的 n 和 s 是局部变量
s = 1
for i in range(1, n + 1):
s *= i
return s
# 访问到的是全局变量 n 10 s 100
print(fact(n), s) # 3628800 100
规则1:局部变量和全局变量是不同变量
- 局部变量是函数内部的占位符,与全局变量可能重名但不同
- 函数运算结束后,局部变量被释放
- 可以使用 global 保留字在函数内部使用全局变量
n, s = 10, 100
def fact(n):
# s = 1 # 局部变量
global s # 使用全局变量 s
for i in range(1, n + 1):
s *= i
return s
print(fact(n), s) # 362880000 362880000
规则2:局部变量为组合数据类型且未创建,等同于全局变量
ls = ["F", "f"]
def func(a):
ls.append(a)
return
func("C")
print(ls) # ['F', 'f', 'C']
ls = ["F", "f"]
def func(a):
ls = []
ls.append(a)
print(ls) # ['C']
return
func("C")
print(ls) # ['F', 'f']
小结:
- 基本数据类型,无论是否重名,局部变量与全局变量不同
- 可以通过global保留字在函数内部声明全局变量
- 组合数据类型,如果局部变量未真实创建,则是全局变量
lambda 函数
.mp4%22%2C%22size%22%3A50075390%2C%22taskId%22%3A%22u2b100a0e-ad7f-45ad-b612-2cd6ed363cf%22%2C%22taskType%22%3A%22upload%22%2C%22url%22%3Anull%2C%22cover%22%3Anull%2C%22videoId%22%3A%22inputs%2Fprod%2Fyuque%2F2023%2F2331396%2Fmp4%2F1688480383338-a201d019-2a15-445c-8698-c677828fcd3c.mp4%22%2C%22download%22%3Afalse%2C%22__spacing%22%3A%22both%22%2C%22id%22%3A%22DIGIn%22%2C%22margin%22%3A%7B%22top%22%3Atrue%2C%22bottom%22%3Atrue%7D%2C%22card%22%3A%22video%22%7D#DIGIn) lambda 函数返回函数名作为结果
- lambda 函数是一种匿名函数,即没有名字的函数
- 使用 lambda 保留字定义,函数名是返回结果
- lambda 函数用于定义简单的、能够在一行内表示的函数
f = lambda x, y: x + y
print(f(10, 15)) # 25
f = lambda: "lambda函数"
print(f()) # lambda函数
谨慎使用 lambda 函数:
- lambda 函数主要用作一些特定函数或方法的参数
- lambda 函数有一些固定使用方式,建议逐步掌握
- 一般情况,建议使用 def 定义的普通函数
单元小结
.mp4%22%2C%22size%22%3A23313968%2C%22taskId%22%3A%22ude9681d3-d3e5-4449-aa88-416bc157226%22%2C%22taskType%22%3A%22upload%22%2C%22url%22%3Anull%2C%22cover%22%3Anull%2C%22videoId%22%3A%22inputs%2Fprod%2Fyuque%2F2023%2F2331396%2Fmp4%2F1688480383492-0ee6c95b-4c8f-4a1a-bc6c-36171ed0320d.mp4%22%2C%22download%22%3Afalse%2C%22__spacing%22%3A%22both%22%2C%22id%22%3A%22O4Ebd%22%2C%22margin%22%3A%7B%22top%22%3Atrue%2C%22bottom%22%3Atrue%7D%2C%22card%22%3A%22video%22%7D#O4Ebd)
- 使用保留字def定义函数,lambda定义匿名函数
- 可选参数(赋初值)、可变参数(*b)、名称传递
- 保留字return可以返回任意多个结果
- 保留字global声明使用全局变量,一些隐式规则
实例 7: 七段数码管绘制
问题分析
.mp4%22%2C%22size%22%3A32556812%2C%22taskId%22%3A%22u82e6411a-f30a-4eee-a359-fc653f7a927%22%2C%22taskType%22%3A%22upload%22%2C%22url%22%3Anull%2C%22cover%22%3Anull%2C%22videoId%22%3A%22inputs%2Fprod%2Fyuque%2F2023%2F2331396%2Fmp4%2F1688480427560-908d1056-4926-476d-af45-2390113e7700.mp4%22%2C%22download%22%3Afalse%2C%22__spacing%22%3A%22both%22%2C%22id%22%3A%22BUg2l%22%2C%22margin%22%3A%7B%22top%22%3Atrue%2C%22bottom%22%3Atrue%7D%2C%22card%22%3A%22video%22%7D#BUg2l)
实例讲解(上)
(1).mp4%22%2C%22size%22%3A202312768%2C%22taskId%22%3A%22u62994d3f-a846-4c83-a49d-21ca26dbc20%22%2C%22taskType%22%3A%22upload%22%2C%22url%22%3Anull%2C%22cover%22%3Anull%2C%22videoId%22%3A%22inputs%2Fprod%2Fyuque%2F2023%2F2331396%2Fmp4%2F1688480427569-f95ed643-3ebb-483c-8841-cc0a2d424e99.mp4%22%2C%22download%22%3Afalse%2C%22__spacing%22%3A%22both%22%2C%22id%22%3A%22Xogip%22%2C%22margin%22%3A%7B%22top%22%3Atrue%2C%22bottom%22%3Atrue%7D%2C%22card%22%3A%22video%22%7D#Xogip) 基本思路:
- 步骤1:绘制单个数字对应的数码管
- 步骤2:获得一串数字,绘制对应的数码管
- 步骤3:获得当前系统时间,绘制对应的数码管
import turtle
def drawLine(draw): # 绘制单段数码管
turtle.pendown() if draw else turtle.penup()
turtle.fd(40)
turtle.right(90)
def drawDigit(digit): # 根据数字绘制七段数码管
drawLine(True) if digit in [2, 3, 4, 5, 6, 8, 9] else drawLine(False)
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(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)) # 通过eval()函数将数字变为整数
def main():
turtle.setup(800, 350, 200, 200)
turtle.penup()
turtle.fd(-300)
turtle.pensize(5)
drawDate("20181010")
turtle.hideturtle()
turtle.done()
main()
实例讲解(下)
(1).mp4%22%2C%22size%22%3A155357059%2C%22taskId%22%3A%22uc9bbee43-4c98-4e17-8a76-9a7dcfd77e5%22%2C%22taskType%22%3A%22upload%22%2C%22url%22%3Anull%2C%22cover%22%3Anull%2C%22videoId%22%3A%22inputs%2Fprod%2Fyuque%2F2023%2F2331396%2Fmp4%2F1688480427591-ff965b43-d5c0-4172-b0cf-2d9ea0f72ad3.mp4%22%2C%22download%22%3Afalse%2C%22__spacing%22%3A%22both%22%2C%22id%22%3A%22MiRuK%22%2C%22margin%22%3A%7B%22top%22%3Atrue%2C%22bottom%22%3Atrue%7D%2C%22card%22%3A%22video%22%7D#MiRuK)
import turtle, time
def drawGap(): # 绘制数码管间隔
turtle.penup()
turtle.fd(5)
def drawLine(draw): # 绘制单段数码管
drawGap()
turtle.pendown() if draw else turtle.penup()
turtle.fd(40)
drawGap()
turtle.right(90)
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.left(180)
turtle.penup()
turtle.fd(20)
def drawDate(date):
turtle.pencolor("red")
for i in date:
if i == "-":
turtle.write("年", font=("Arial", 18, "normal"))
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))
def main():
turtle.setup(800, 350, 200, 200)
turtle.penup()
turtle.fd(-350)
turtle.pensize(5)
# drawDate('2018-10=10+')
drawDate(time.strftime("%Y-%m=%d+", time.gmtime()))
turtle.hideturtle()
turtle.done()
main()
举一反三
.mp4%22%2C%22size%22%3A57162767%2C%22taskId%22%3A%22uc8e13a9f-5aa6-4974-b4f6-5883585fed6%22%2C%22taskType%22%3A%22upload%22%2C%22url%22%3Anull%2C%22cover%22%3Anull%2C%22videoId%22%3A%22inputs%2Fprod%2Fyuque%2F2023%2F2331396%2Fmp4%2F1688480427587-d2ef7272-47c5-4121-8fef-93f58c1e0839.mp4%22%2C%22download%22%3Afalse%2C%22__spacing%22%3A%22both%22%2C%22id%22%3A%22nOLRg%22%2C%22margin%22%3A%7B%22top%22%3Atrue%2C%22bottom%22%3Atrue%7D%2C%22card%22%3A%22video%22%7D#nOLRg) 理解方法思维
- 模块化思维:确定模块接口,封装功能
- 规则化思维:抽象过程为规则,计算机自动执行
- 化繁为简:将大功能变为小功能组合,分而治之
代码复用与函数递归
单元开篇
.mp4%22%2C%22size%22%3A10672531%2C%22taskId%22%3A%22u430c691c-72bb-4d8d-abf7-2ae059238e1%22%2C%22taskType%22%3A%22upload%22%2C%22url%22%3Anull%2C%22cover%22%3Anull%2C%22videoId%22%3A%22inputs%2Fprod%2Fyuque%2F2023%2F2331396%2Fmp4%2F1688480440724-5f80e90d-994d-41e1-98ff-81f33f9ef97c.mp4%22%2C%22download%22%3Afalse%2C%22__spacing%22%3A%22both%22%2C%22id%22%3A%22EbmGa%22%2C%22margin%22%3A%7B%22top%22%3Atrue%2C%22bottom%22%3Atrue%7D%2C%22card%22%3A%22video%22%7D#EbmGa)
代码复用与模块化设计
.mp4%22%2C%22size%22%3A105728177%2C%22taskId%22%3A%22uad27252e-7b85-4b33-9582-16fb9ebca51%22%2C%22taskType%22%3A%22upload%22%2C%22url%22%3Anull%2C%22cover%22%3Anull%2C%22videoId%22%3A%22inputs%2Fprod%2Fyuque%2F2023%2F2331396%2Fmp4%2F1688480441437-1ba4a3cb-34b3-43e0-a3e8-35c6dc11c148.mp4%22%2C%22download%22%3Afalse%2C%22__spacing%22%3A%22both%22%2C%22id%22%3A%22uZe0l%22%2C%22margin%22%3A%7B%22top%22%3Atrue%2C%22bottom%22%3Atrue%7D%2C%22card%22%3A%22video%22%7D#uZe0l) 代码复用:把代码当成资源进行抽象
- 代码资源化:程序代码是一种用来表达计算的”资源”
- 代码抽象化:使用函数等方法对代码赋予更高级别的定义
- 代码复用:同一份代码在需要时可以被重复使用
函数 和 对象 是代码复用的两种主要形式
模块化设计:分而治之
- 通过函数或对象封装将程序划分为模块及模块间的表达
- 具体包括:主程序、子程序和子程序间关系
- 分而治之:一种分而治之、分层抽象、体系化的设计思想
模块化设计:紧耦合、松耦合
- 紧耦合:两个部分之间交流很多,无法独立存在
- 松耦合:两个部分之间交流较少,可以独立存在
- 模块内部紧耦合、模块之间松耦合
函数递归的理解
.mp4%22%2C%22size%22%3A46838195%2C%22taskId%22%3A%22u7150fe42-bdbb-4a3f-805b-0f9595d9fc7%22%2C%22taskType%22%3A%22upload%22%2C%22url%22%3Anull%2C%22cover%22%3Anull%2C%22videoId%22%3A%22inputs%2Fprod%2Fyuque%2F2023%2F2331396%2Fmp4%2F1688480449504-8efd248b-8bb6-4447-82fd-e20401b61100.mp4%22%2C%22download%22%3Afalse%2C%22__spacing%22%3A%22both%22%2C%22id%22%3A%22hlwF3%22%2C%22margin%22%3A%7B%22top%22%3Atrue%2C%22bottom%22%3Atrue%7D%2C%22card%22%3A%22video%22%7D#hlwF3) 递归:函数定义中调用函数自身的方式
递归的两个关键特征:
- 链条:计算过程存在递归链条
- 基例:存在一个或多个不需要再低递归的基例
注意读音:
递归类似数学归纳法:
- 证明当n取第一个值n0时命题成立
- 假设当nk时命题成立,证明当n=nk+1时命题也成立
递归是数学归纳法思维的编程体现。
函数递归的调用过程
.mp4%22%2C%22size%22%3A121504202%2C%22taskId%22%3A%22u4d3317c4-1b17-4d42-801c-bd8507b0d26%22%2C%22taskType%22%3A%22upload%22%2C%22url%22%3Anull%2C%22cover%22%3Anull%2C%22videoId%22%3A%22inputs%2Fprod%2Fyuque%2F2023%2F2331396%2Fmp4%2F1688480450148-63af4042-2e2f-45d3-a723-b2caf3da550f.mp4%22%2C%22download%22%3Afalse%2C%22__spacing%22%3A%22both%22%2C%22id%22%3A%22XsFGx%22%2C%22margin%22%3A%7B%22top%22%3Atrue%2C%22bottom%22%3Atrue%7D%2C%22card%22%3A%22video%22%7D#XsFGx)
def fact(n):
if n == 0:
return 1
else:
return n * fact(n - 1)
print(fact(0)) # 1
print(fact(1)) # 1
print(fact(2)) # 2
print(fact(3)) # 6
print(fact(4)) # 24
print(fact(5)) # 120
递归的实现:函数 + 分支语句
- 递归本身是一个函数,需要函数定义方式描述
- 函数内部,采用分支语句对输入参数进行判断
- 基例和链条,分别编写对应代码
函数递归实例解析
.mp4%22%2C%22size%22%3A233427107%2C%22taskId%22%3A%22ud096b704-cf83-464b-91e7-d0d3b504878%22%2C%22taskType%22%3A%22upload%22%2C%22url%22%3Anull%2C%22cover%22%3Anull%2C%22videoId%22%3A%22inputs%2Fprod%2Fyuque%2F2023%2F2331396%2Fmp4%2F1688480474820-96f261ae-db5b-4747-9048-5a22fdaba457.mp4%22%2C%22download%22%3Afalse%2C%22__spacing%22%3A%22both%22%2C%22id%22%3A%22X2hJn%22%2C%22margin%22%3A%7B%22top%22%3Atrue%2C%22bottom%22%3Atrue%7D%2C%22card%22%3A%22video%22%7D#X2hJn)
def rvs(s):
if s == "":
return s
else:
return rvs(s[1:]) + s[0]
def f(n):
if n == 1 or n == 2:
return 1
else:
return f(n - 1) + f(n - 2)
count = 0
def hanoi(n, src, dst, mid):
global count
if n == 1:
print("{}:{} -> {}".format(1, src, dst))
count += 1
else:
hanoi(n - 1, src, mid, dst)
print("{}:{} -> {}".format(n, src, dst))
count += 1
hanoi(n - 1, mid, dst, src)
hanoi(3, 'A', 'B', 'C')
'''
1:A -> B
2:A -> C
1:B -> C
3:A -> B
1:C -> A
2:C -> B
1:A -> B
'''
单元小结
.mp4%22%2C%22size%22%3A21931894%2C%22taskId%22%3A%22u25fa0f8c-2174-4765-a674-46c950db424%22%2C%22taskType%22%3A%22upload%22%2C%22url%22%3Anull%2C%22cover%22%3Anull%2C%22videoId%22%3A%22inputs%2Fprod%2Fyuque%2F2023%2F2331396%2Fmp4%2F1688480487665-e4e731e6-c188-4697-a28a-6970bc86eca0.mp4%22%2C%22download%22%3Afalse%2C%22__spacing%22%3A%22both%22%2C%22id%22%3A%22mDtRC%22%2C%22margin%22%3A%7B%22top%22%3Atrue%2C%22bottom%22%3Atrue%7D%2C%22card%22%3A%22video%22%7D#mDtRC)
- 模块化设计:松耦合、紧耦合
- 函数递归的2个特征:基例和链条
- 函数递归的实现:函数 + 分支结构
模块 4: PyInstaller 库的使用
PyInstaller 库基本介绍
.mp4%22%2C%22size%22%3A46437275%2C%22taskId%22%3A%22u79240b87-870a-4f48-9184-5f0ac22b740%22%2C%22taskType%22%3A%22upload%22%2C%22url%22%3Anull%2C%22cover%22%3Anull%2C%22videoId%22%3A%22inputs%2Fprod%2Fyuque%2F2023%2F2331396%2Fmp4%2F1688480488813-2f6ca3a6-0cdf-4a5e-a8ef-a4ce1cf622d1.mp4%22%2C%22download%22%3Afalse%2C%22__spacing%22%3A%22both%22%2C%22id%22%3A%22ieDpI%22%2C%22margin%22%3A%7B%22top%22%3Atrue%2C%22bottom%22%3Atrue%7D%2C%22card%22%3A%22video%22%7D#ieDpI)
- PyInstaller 库的作用:将
**.py**
源代码转换成无需源代码的可执行文件 - PyInstaller 库是第三方库
- 官方网站:http://www.pyinstaller.org
- 第三方库:使用前需要额外安装
- 安装第三方库需要使用 pip 工具
- PyInstaller 库的安装:
pip install pyinstaller
、pip3 install pyinstaller
huyouda@HuyoudeMacBook-Pro ~ % pip3 install pyinstaller
Collecting pyinstaller
Downloading pyinstaller-5.13.0-py3-none-macosx_10_13_universal2.whl (928 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 928.8/928.8 kB 703.5 kB/s eta 0:00:00
Requirement already satisfied: setuptools>=42.0.0 in /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages (from pyinstaller) (65.5.0)
Collecting altgraph (from pyinstaller)
Downloading altgraph-0.17.3-py2.py3-none-any.whl (21 kB)
Collecting pyinstaller-hooks-contrib>=2021.4 (from pyinstaller)
Downloading pyinstaller_hooks_contrib-2023.5-py2.py3-none-any.whl (273 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 273.1/273.1 kB 1.8 MB/s eta 0:00:00
Collecting macholib>=1.8 (from pyinstaller)
Downloading macholib-1.16.2-py2.py3-none-any.whl (38 kB)
Installing collected packages: altgraph, pyinstaller-hooks-contrib, macholib, pyinstaller
Successfully installed altgraph-0.17.3 macholib-1.16.2 pyinstaller-5.13.0 pyinstaller-hooks-contrib-2023.5
PyInstaller 库使用说明
.mp4%22%2C%22size%22%3A99779970%2C%22taskId%22%3A%22ua2446aad-4daf-4be0-a25f-bf7bc25f7cf%22%2C%22taskType%22%3A%22upload%22%2C%22url%22%3Anull%2C%22cover%22%3Anull%2C%22videoId%22%3A%22inputs%2Fprod%2Fyuque%2F2023%2F2331396%2Fmp4%2F1688480501343-a1a128ed-de40-4561-b0c8-46f1aca56937.mp4%22%2C%22download%22%3Afalse%2C%22__spacing%22%3A%22both%22%2C%22id%22%3A%22Iu72r%22%2C%22margin%22%3A%7B%22top%22%3Atrue%2C%22bottom%22%3Atrue%7D%2C%22card%22%3A%22video%22%7D#Iu72r)
实例 8: 科赫雪花小包裹
问题分析
.mp4%22%2C%22size%22%3A60543272%2C%22taskId%22%3A%22ue29c7f29-7211-41cd-84d9-04ad05194bd%22%2C%22taskType%22%3A%22upload%22%2C%22url%22%3Anull%2C%22cover%22%3Anull%2C%22videoId%22%3A%22inputs%2Fprod%2Fyuque%2F2023%2F2331396%2Fmp4%2F1688480502601-b3645403-80c6-43fa-87cc-d92e15e050f2.mp4%22%2C%22download%22%3Afalse%2C%22__spacing%22%3A%22both%22%2C%22id%22%3A%22rO4Z7%22%2C%22margin%22%3A%7B%22top%22%3Atrue%2C%22bottom%22%3Atrue%7D%2C%22card%22%3A%22video%22%7D#rO4Z7)
实例讲解(上)
(1).mp4%22%2C%22size%22%3A112743253%2C%22taskId%22%3A%22uc7d8148e-a693-4388-b6d2-5214ff6baaa%22%2C%22taskType%22%3A%22upload%22%2C%22url%22%3Anull%2C%22cover%22%3Anull%2C%22videoId%22%3A%22inputs%2Fprod%2Fyuque%2F2023%2F2331396%2Fmp4%2F1688480504481-4a351cd3-5c2b-4058-9e86-de92155d8a38.mp4%22%2C%22download%22%3Afalse%2C%22__spacing%22%3A%22both%22%2C%22id%22%3A%22JMUdt%22%2C%22margin%22%3A%7B%22top%22%3Atrue%2C%22bottom%22%3Atrue%7D%2C%22card%22%3A%22video%22%7D#JMUdt)
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.penup()
turtle.goto(-300, -50)
turtle.pendown()
turtle.pensize(2)
koch(600, 3) # 0阶科赫曲线长度,阶数
turtle.hideturtle()
turtle.done()
main()
实例讲解(下)
(1).mp4%22%2C%22size%22%3A38716633%2C%22taskId%22%3A%22u2bbfdbd6-fb95-4570-a925-765567000ea%22%2C%22taskType%22%3A%22upload%22%2C%22url%22%3Anull%2C%22cover%22%3Anull%2C%22videoId%22%3A%22inputs%2Fprod%2Fyuque%2F2023%2F2331396%2Fmp4%2F1688480510940-cc83ccc9-309b-4f8c-8903-1857f20e77c8.mp4%22%2C%22download%22%3Afalse%2C%22__spacing%22%3A%22both%22%2C%22id%22%3A%22vEdOW%22%2C%22margin%22%3A%7B%22top%22%3Atrue%2C%22bottom%22%3Atrue%7D%2C%22card%22%3A%22video%22%7D#vEdOW)
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(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()
turtle.done()
main()
举一反三
.mp4%22%2C%22size%22%3A30542763%2C%22taskId%22%3A%22u92ea7110-1aa3-46e4-9e6a-ea3df913696%22%2C%22taskType%22%3A%22upload%22%2C%22url%22%3Anull%2C%22cover%22%3Anull%2C%22videoId%22%3A%22inputs%2Fprod%2Fyuque%2F2023%2F2331396%2Fmp4%2F1688480531293-4ad1cc9f-8f03-4e0a-9075-6bf5ce638d4a.mp4%22%2C%22download%22%3Afalse%2C%22__spacing%22%3A%22both%22%2C%22id%22%3A%22WkBnW%22%2C%22margin%22%3A%7B%22top%22%3Atrue%2C%22bottom%22%3Atrue%7D%2C%22card%22%3A%22video%22%7D#WkBnW)
练习
.mp4%22%2C%22size%22%3A8825295%2C%22taskId%22%3A%22u2db7a52c-8ad2-43f4-988c-aaa0dfdf98f%22%2C%22taskType%22%3A%22upload%22%2C%22url%22%3Anull%2C%22cover%22%3Anull%2C%22videoId%22%3A%22inputs%2Fprod%2Fyuque%2F2023%2F2331396%2Fmp4%2F1688480532470-b974840f-bea7-45e7-90b5-4e54f69779cb.mp4%22%2C%22download%22%3Afalse%2C%22__spacing%22%3A%22both%22%2C%22id%22%3A%22DN7bI%22%2C%22margin%22%3A%7B%22top%22%3Atrue%2C%22bottom%22%3Atrue%7D%2C%22card%22%3A%22video%22%7D#DN7bI)
单选题
def f(a, b):
a = 4
return a + b
def main():
a = 5
b = 6
print(f(a, b), a + b)
main() # 10 11
def func(a, b):
c = a ** 2 + b
b = a
return c
a = 10
b = 100
c = func(a, b) + a
print(a, b, c) # 10 100 210
连续质数计算
def prime(m):
for i in range(2, m):
if m % i == 0:
return False
return True
n = eval(input())
n_ = int(n)
n_ = n_ + 1 if n_ < n else n_
count = 5
while count > 0:
if prime(n_):
if count > 1:
print(n_, end=",")
else:
print(n_, end="")
count -= 1
n_ += 1
"""
12
13,17,19,23,29
"""
这个代码注意:
(1) 需要对输入小数情况进行判断,获取超过该输入的最小整数(这里没用floor()函数)
(2) 对输出格式进行判断,最后一个输出后不增加逗号(这里没用.join()方法)
实例7:七段数码管绘制
import turtle as t
import time
def drawGap(): # 绘制数码管间隔
t.penup()
t.fd(5)
def drawLine(draw): # 绘制单段数码管
drawGap()
t.pendown() if draw else t.penup()
t.fd(40)
drawGap()
t.right(90)
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)
t.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)
t.left(180)
t.penup()
t.fd(20)
def drawDate(date):
t.pencolor("red")
for i in date:
drawDigit(eval(i))
def main():
t.setup(800, 350, 200, 200)
t.penup()
t.fd(-300)
t.pensize(5)
drawDate(time.strftime("%Y%m%d", time.gmtime()))
t.done()
main()
这是本课程的实例7:
基本思路:
步骤 1:绘制单个数字对应的码管
步骤 2:获得当前系统时间,变成字符串,绘制对应的码管
思维方法:
- 模块化思维:确定接口,封装功能
- 规则化思维:抽象过程为规则,计算机自动执行
- 化繁为简:将大功能变小组合,分而治之
实例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(level):
turtle.setup(600, 600)
turtle.penup()
turtle.goto(-200, 100)
turtle.pendown()
turtle.pensize(2)
koch(400, level)
turtle.right(120)
koch(400, level)
turtle.right(120)
koch(400, level)
turtle.hideturtle()
try:
level = eval(input("请输入科赫曲线的阶: "))
main(level)
except:
print("输入错误")
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(level):
turtle.setup(600, 600)
turtle.penup()
turtle.goto(-200, 100)
turtle.pendown()
turtle.pensize(2)
turtle.speed("fastest") # 设置绘图速度为最快
turtle.tracer(100) # 每100次绘图操作更新一次屏幕
koch(400, level)
turtle.right(120)
koch(400, level)
turtle.right(120)
koch(400, level)
turtle.hideturtle()
turtle.update() # 在绘图结束后更新屏幕
turtle.done() # 绘图完毕后不要自动关闭窗口
try:
level = eval(input("请输入科赫曲线的阶: "))
main(level)
except:
print("输入错误")
这是本课程的实例8:
(1) 基本思路:
- 递归思想:函数 +分支
- 递归链条:线段的组合
- 递归基例:初始线段
(2) 分形几何是一种迭代的图,广泛存在于自然界中,请尝试选择一个新曲线绘制:
- 康托尔集、谢宾斯基三角形门格海绵 …
- 龙形曲线 、空间填充科赫…
- 函数递归的深入应用 …
任意累积
def cmul(a, *b):
m = a
for i in b:
m *= i
return m
print(eval("cmul({})".format(input())))
"""
1,2,3,4
24
"""
该程序需要注意两个内容:
- 无限制参数数量函数定义的方法,其中 b 在函数 cmul 中表达除了 a 之外的所有输入参数
- 以字符串形式调用函数的方法,”cmul()” 与 eval() 的组合,提供了很多灵活性
斐波那契数列计算
def fbi(n):
if n == 1 or n == 2:
return 1
else:
return fbi(n - 1) + fbi(n - 2)
n = eval(input())
print(fbi(n))
"""
4
3
"""
基本的递归使用,不解释。
汉诺塔实践
steps = 0
def hanoi(src, des, mid, n):
global steps
if n == 1:
steps += 1
print("[STEP{:>4}] {}->{}".format(steps, src, des))
else:
hanoi(src, mid, des, n - 1)
steps += 1
print("[STEP{:>4}] {}->{}".format(steps, src, des))
hanoi(mid, des, src, n - 1)
N = eval(input())
hanoi("A", "C", "B", N)
"""
4
[STEP 1] A->B
[STEP 2] A->C
[STEP 3] B->C
[STEP 4] A->B
[STEP 5] C->A
[STEP 6] C->B
[STEP 7] A->B
[STEP 8] A->C
[STEP 9] B->C
[STEP 10] B->A
[STEP 11] C->A
[STEP 12] B->C
[STEP 13] A->B
[STEP 14] A->C
[STEP 15] B->C
"""
汉诺塔实例十分经典,学习每门语言都要写一遍。
这个例子要注意:全局变量的使用以及递归的用法。递归用法注意:函数定义+分支表示。