本章进入第五个部分函数和代码复用函数定义与使用
实例7:七段数码管绘制
代码复用和函数递归
模块4:PyInstaller库的使用
实例8:科赫雪花小包裹
函数定义与使用函数的理解与定义
函数的使用和调用过程
函数的参数传递
函数的返回值
局部变量和全局变量
lambda函数
函数的理解与定义函数是一段具有特定功能,可重复使用的语句组
函数是一种功能的抽象,一般函数表达特定功能
两个作用:降低编程难度和代码复用
def <函数名>(<参数(0个或多个)>):
<函数体>
return <返回值>
函数的使用和调用过程
执行代码需要函数的调用
函数的参数传递
函数可以有参数,也可以没有参数,但必须保留括号
在函数定义时可以指定某些参数为默认值,构成可选参数
def <函数名>(<非可选参数>,<可选参数>):
<函数体>
return <返回值>
#可选参数要放在非可选参数之后
函数定义时可以设计可变数量参数,即不确定参数的总数量
def <函数名>(<参数>,*b):
<函数体>
return <返回值>
函数调用可以用位置传递和名称传递两种方式
函数的返回值
函数可以返回0个或多个结果
局部变量和全局变量
规则介绍局部变量和全局变量是不同变量局部变量是函数内部的占位符,与全局变量可能重名但不同
函数运算结束后,局部变量被释放
可以使用global保留字在函数内部使用全局变量局部变量是组合数据类型且未创建,等同于全局变量
如果真实创建,则其为局部变量
lambda函数lambda函数返回函数名作为结果lambda函数是一种匿名函数
使用lambda保留字定义,函数名是返回结果
lambda函数用于定义简单的、能够在一行内表示的函数
lambda函数主要用于一些特定函数或方法的参数
lambda函数有一些固定的使用方式,建议逐步掌握
一般情况建议使用def定义的普通函数
<函数名>=lambda<参数>:<表达式>
实例7:七段数码管绘制
基本思路绘制单个数字对应的数码管
获得一串数字,绘制对应的数码管
获得当前系统时间,绘制对应的数码管
实现代码
#SevenDigitsDrawV1.py
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()
改进版代码
#SevenDigitsDrawV2.py
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:
renturn 1
else:
renturn n*fact(n-1)
函数+分支语句递归本身是一个函数,需要函数定义方式描述
函数内部,采用分支语句对输入参数进行判断
基例和链条,分别编写对应代码
例子1:字符串反转
将字符串s反转输出
方法1
s[::-1]
方法2
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:汉诺塔问题
count=0
def hanoi(n,sec,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","C","B")
print(count)
模块4:PyInstaller库的使用
将.py源代码转换成无需源代码的可执行文件
常用参数
实例8:科赫雪花小包裹
科赫曲线:雪花曲线递归思想:函数+分支
递归链条:线段的组合
递归基例:初识线段
求解代码
#KochDrawV1.py
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()
main()
举一反三绘制条件的拓展修改分形几何的绘制阶数
修改科赫曲线的基本定义及旋转角度
修改绘制科赫雪花的基本框架图形