赶时髦,python这么火,学习一哈

1.Python基本语法元素

1.1 程序设计基本方法

计算机发展历史上最重要的预测法则     摩尔定律:单位面积集成电路上可容纳晶体管数量约2年翻倍 cpu/gpu、内存、硬盘、电子产品价格等都遵循此定律

\"image_thumb3_thumb1\"

50年来计算机是唯一一个指数发展的领域

 

源代码、目标代码(机器代码)

编译、解释

静态语言、脚本语言

静态语言编译器一次性生成目标代码,优化更冲份,程序运行速度更快

脚本语言 执行程序时需要源代码,维护更灵活

   

程序的基本设计方法IPO

I:input  文件输入、网络输入、控制台输入、交互界面输入、内部参数输入

P:process 处理

O:output 控制台输出、图形输出、文件输出、网络输出、操作系统内部输出

6个步骤:

-分析问题:分析问题的计算部分,想清楚

-划分边界:划分问题的功能边界,规划IPO

-设计算法:设计问题的求解算法,关注算法

-编程

-调试测试

-升级维护

3个精简步骤:确定IPO、编程、调试运行

计算思维(编程体现了一种抽象交互关系、自动化执行的思维模式)、逻辑思维、实证思维   

1.2 Python开发环境配置

python 蟒蛇

psf 拥有者,开放、开源精神

Guido van Rossum创立

2002年 2.x

2008年 3.x

python3不兼容python2

交互式、文件式

 

linux自带python2和python3,无需安装,不过没有pip,要安装apt install python3-pip

trouble shooting:python3中import turtle  ModuleNotFoundError: No module named 'tkinter'报错

\"image_thumb4_thumb\"

apt install python3-tk

apt install tk-dev或yum install tk-devel

然后import turtle不报错了

 

test一下

test1

\"image_thumb5_thumb\"

 

test2

\"image_thumb10_thumb\"

\"image_thumb11_thumb\"

test3

\"image_thumb8_thumb\"

\"image_thumb9_thumb\"

1.3 实例1:温度转换

实例1:温度转换

需求:摄氏度与华氏度相互转换

#TempConvert.py
TempStr = input("请输入带有符号的温度值: ")
if TempStr[-1] in ['F', 'f']:
    C = (eval(TempStr[0:-1]) - 32)/1.8
    print("转换后的温度是{:.2f}C".format(C))
elif TempStr[-1] in ['C', 'c']:
    F = 1.8*eval(TempStr[0:-1]) + 32
    print("转换后的温度是{:.2f}F".format(F))
else:
    print("输入格式错误")

1.4 Python程序语法元素分析

程序的格式框架:

代码高亮 是辅助

缩进是语法要求  一般4个空格或者1个tab  表达代码间包含和层次关系的唯一手段 

注释:单行注释 #       多行注释  ''' '''


命名:给变量关联标识符的过程

命名大小写敏感、首字符不能是数字、不与保留字相同

保留字:被编程语言内部定义并保留使用的标识符 也大小写敏感 33个

\"Image_thumb_thumb\" 

 


数据类型

字符串  

用‘’或“”

正向递增序号、反向递减序号  正向0开始编号

索引: 可以使用[M]索引其中单个字符

切片:可以使用[M:N]返回其中一段子串,从第M到第N-1个字符

\"image\" 

 

数字类型:整数、浮点数

列表:表示0到多个数据组成的有序序列,采用,分隔各元素,使用in判断一个元素是否在列表中


=   赋值主语句

分支语句if elif else构成

eval 评估函数 去除参数最外侧引号并执行余下语句的函数

 

垂直输出hello world

for i in "Hello World":

   print(i)

 

输出

x = input()

print(eval(x)**0,eval(x)**1,eval(x)**2,eval(x)**3,eval(x)**4,eval(x)**5)  

2. Python基本图形绘制

2.1 深入理解Python语言

计算机演进过程:

1946-1981 计算机系统结构时代  计算能力问题        1981年个人pc诞生                      

1981-2008 网络和视窗时代  交互问题                          2008 Android诞生   标志pc转向移动            

2008-2016 复杂信息系统时代 数据问题                       2016年alpha go打败人类               

2017-  人工智能时代 人类的问题

 

新计算时代  过度到人工智能时代的中间时代


编程语言的初心 

不完全统计600多中语言    常用的也就那么20来种

python已经在tiobe排行超过C++跃居第三

\"Image1_thumb_thumb\" 

\"Image2_thumb_thumb\" 


Python语言是通用语言、脚本语言、开源语言、跨平台语言、多模型语言 

--强制可读性

--较少的底层语法元素

--多种编程方式

--支持中文字符

--C代码量的10%                  语法简洁    *10

--13万第三方库                  生态高产    *10

--快速增长的计算生态 每年2万

--避免重复造轮子

--开放共享

--跨操作系统平台

 

人生苦短 我学Python

    --C/C++:C归C  Python归Python

    --Java:针对特定开发和岗位需求

    --HTML/CSS/JS:不可替代的前端技术,全栈能力

    -R/GO/Matlab等:特定领域

 

Python是最高产的程序设计语言

    --掌握抽象并求解计算问题综合能力的语言

    -了解产业界解决复杂计算问题方法的语言

    -享受利用编程将创新变为实现乐趣的语言

 

工具决定思维:关注工具变革的力量!


\"image\"

\"image\"

python具有最庞大的生态库,是唯一的超级语言,前进步伐不可阻挡

2.2 实例2:Python蟒蛇绘制

#PythonDraw.py
import turtle
turtle.setup(650, 350, 200, 200)
turtle.penup()
turtle.fd(-250)
turtle.pendown()
turtle.pensize(25)
turtle.pencolor("purple")
turtle.seth(-40)
for i in range(4):
    turtle.circle(40, 80)
    turtle.circle(-40, 80)
turtle.circle(40, 80/2)
turtle.fd(40)
turtle.circle(16, 180)
turtle.fd(40 * 2/3)
turtle.done()

2.3 模块1: turtle库的使用

turtle库基本介绍

import 保留字 引入turtle绘图库 海龟绘图体系

turtle库是turtle绘图体系的Python实现  1969年诞生,主要用于程序设计入门 Python的标准库之一 入门级的图形绘制函数库

Python计算生态=标准库+第三方库

库library,包package,模块module ,统称模块

有一只海龟,其实在窗体正中心,在画布上游走,走过的轨迹绘制的图形,海龟由程序控制,可以变换颜色宽度


turtle绘图窗体布局

turtle的一个画布空间 最小单位是像素

屏幕坐标系:屏幕左上角为0 0

turtle.setup(width,height,startx,starty)后两个可选 默认屏幕中央  并不是必须的   用来设置窗体大小和窗体左上角与屏幕左上角的相对位置


turtle空间坐标系

绝对坐标  海龟在屏幕中央 记为(0,0)坐标原点   turtle.goto(x,y) 

海龟坐标  以海归的视角turtle.fd(d),turtle.bk(d),turtle.circle(r,angle) 左侧r为止为中心行走angle角度的弧线


turtle角度坐标体系

绝对角度 改变海龟前进方向 turtle.seth(angle)

\"image\" 

海龟角度 turtle.left(angle),turtle.right(angle)

\"image\"


RGB色彩体系 0-255整数或 0-1 的小数

 \"image\"

\"image\"

默认采用小数制,可切换为整数制  turtle.colormode(mode) mode为1.0或255 

2.4 turtle语法元素分析

库引用

扩充Python程序功能的方式 使用import保留字完成,采用<a>.<b>()的编码风格  

from turtle import*    缺点 函数重名   适用于短的程序

from turtle import函数名 

可以as保留字起别名 import turtle as t    --推荐使用


画笔控制函数

画笔操作后一直有效,一般成对出现

-turtle.penup() 别名turtle.pu() 抬起画笔,海龟在飞行

-turtle.pendown() 别名turtle.pd() 落下画笔,海龟在爬行

画笔设置后一直有效,直到下次设置

-turtle.pensize(width) 别名turtle.width(width)  画笔宽度,海龟腰围

-turtle.pencolor(color) color为颜色字符串或rgb值 画笔颜色,海龟在涂装 

      -颜色字符串 turtle.pencolor("purple")

       -rgb小数  turtle.pencolor(0.63,0.13,0.94)

       -rgb元组值  turtle.pencolor((0.63,0.13,0.94))


运动控制函数

控制海龟行进:走直线&走曲线

-turtle.forward(d) 别名 turtle.fd(d)  向前行进,海龟走直线   d可以为负数

-turtle.circle(r,extent=none) 根据半径r绘制extent角度的弧线 r默认圆心在海龟左侧r距离的位置  -extent绘制角度,默认是360度


方向控制函数

turtle.setheading() 别名turtle.seth() 控制海龟面对方向:绝对角度 海龟角度

turtle.left() turtle.right()


循环语句

for in 保留字

range() 产生循环计算序列 range(N) range(M:N)    0到N-1 M到N-1

turtle.done() 运行结束 不退出  需要手工退出  去掉就自动退出了

3. 基本数据类型

3.1 数字类型及其操作

整数类型:可正可负 取值无限 pow(x,y) x的y次方

4种进制表示:10进制、二进制0b或0B开头 0b010、8进制0o或0O、16进制0x或0X


浮点型 10的308次方 精度达到:10的-16次方小数 即53位二进制   与数学中实数一致

不确定尾数 (浮点数运算)不是bug  53位二进制表示浮点数的小数部分 约10的-16次方  计算机中的二进制和十进制不完全对等 

二进制表示小数,可以无限接近,但不完全相同

0.1+0.2 结果接近0.3

0.1+0.2 == 0.3  false    用round(x,d)处理不确定尾数   不确定位数一般发生在10的-16次方左右

科学计数法  e或E作为幂的符号,10为基数  <a>e<b>  4.3e-3


复数类型 z.real z.imag  获得实部和虚部


数值运算操作符

x+y x-y x*y x/y x//y  +x -y x%y x**y         ps:x/y 是浮点数  别的语言中不是这样

二元操作符有对应的增强赋值操作符

x op =y   x+=y x-=y x*=y x/=y x//=y x%=y x**=y

类型间可以混合运算 结果生成为“最宽”的类型 隐式转换  整数->浮点数->复数  如123+4.0=127.0

数值运算函数

abs(x) 绝对值

divmod(x,y) 商余    divmod(10,3)  结果是二元数(3,1)

pow(x,y[,z]) 幂余

round(x[,d]) 四舍五入

max(x1,x2,..)

min(x1,x2,..)

int(x) 显示类型转换,  变为整数,舍弃小数

float(x)  转浮点数

complex(x)  转复数

3.2 实例3:天天向上的力量

问题分析:持续的价值    一年365天每天进步1%,累计进步多少?相反,每天退步1%,累计剩下多少?如果三天打渔二天晒网呢?

print("向上{:.2f},向下{:.2f}".format(pow(1.001,365),pow(0.999,365)))     结果:  向上1.44,向下0.69


如果是0.5% 1%呢

#DayDayUp1.py
factor=0.005
print("向上{:.2f},向下{:.2f}".format(pow(1+factor,365),pow(1-factor,365)))

结果:

0.5% :向上6.17,向下0.16

1%:向上37.78,向下0.03


如果是工作日的力量?工作日进步1%,休息日退步1%

#DayDayUp.py
dayup=1.0
factor=0.01
for i in range(365):
    if i % 7 in [6,0]:
        dayup *= 1-factor
    else:
        dayup *= 1+factor
print("{:.2f}".format(dayup))

结果:4.63


工作日的努力要达到多少才能和每天努力1%一样?

#DayDayUp.py
def dayUP(factor):
    dayup=1.0
    for i in range(365):
        if i % 7 in [6,0]:
            dayup *= 1-0.01
        else:
            dayup *= 1+factor
    return dayup;
dayfactor = 0.01
while dayUP(dayfactor) < 37.78:
    dayfactor += 0.001
print("工作日的努力参数是:{:.3f} ".format(dayfactor))

结果是:1.9%


\"image\"

3.3 字符串类型及操作

四种字符串表示方法:

由一对单引号或双引号表示单行字符串

由一对三引号或三双引号表示多行字符串            

三单引号表示字符串,程序啥都不执行,相当于注释,python实际没有真正提供多行注释


[M:N:K]根据步长对字符串切片 M和N均可以缺失,表示至开头或至结尾

[::-1]倒序

\"image\"

转义符  b 回退  n 换行  r 回车光标移动到行首


字符串操作符

x+y 连接两个字符串

n*x或x*n 复制n次字符串x

x in s


字符串处理函数 

len(x) 字符串长度    中英文长度都是1

str(x) 强制类型转换为字符串  和eval相反操作

hex(x)  整数x转变为8进制形式

oct(x) 整数x转变为16进制形式

chr(x) 将unicode编码返回其字符形式

ord(x)  上面的反操作

unicode编码 统一字符编码 从0到1114111(0x10FFFF) Python字符串每个字符都是unicode编码

\"image\"


字符串处理方法 

<a>.<b>  形式 面向对象的术语 表示对象的动作

8个字符串处理方法

.lower() .upper()   大小写转换

.split(sep=None)  字符串分割,返回一个列表    例:"a,b,c".split(',')结果是['a', 'b', 'c']

.count(sub)       字符串sub在其中出现次数

.replace(old,new)         字符串替换

.center(width[,fillchar])     字符串格式处理,字符串居中  例: 'python'.center(30,'=')  结果'============python============'

.strip(chars)     去除字符换两边字符         如:'= python= '.strip(' =np')结果'ytho'

.join(iter) 填充字符    如:','.join('12345')结果'1,2,3,4,5'


字符串类型的格式化  

格式化是对字符串进行格式化表达的方式

.format方法    用法:<模板字符串>.format(<逗号分隔的参数>)

相当于占位信息符,只在字符串中有用

\"image\"

\"image\"

 

format方法的格式控制  6种格式控制标记

 

\"image\"

分为2组

前三个参数是一组   默认填充空格左对齐

如:            "{:=^20}".format("python")     结果:           '=======python======='

如:            "{0:,.2f}".format(12345.6789)   结果    '12,345.68' 

如:"{0:b} {0:c} {0:d} {0:o} {0:x} {0:X}".format(425)           结果'110101001 Ʃ 425 651 1a9 1A9' 

如: "{0:e} {0:E}{0:f} {0:%}".format(3.14)  结果     '3.140000e+00 3.140000E+003.140000 314.000000%'

3.4 模块2:time库的使用

time库是Python中处理时间的标准库

时间获取

time()  获取当前时间戳,即计算机系统内部时间值,浮点数  1970年1月1日0点0分开始到当前系统以秒为单位的浮点数       如:1537763974.4934046

ctime() 获取当前时间,返回字符串,人类易读  如:'Mon Sep 24 12:41:59 2018'

gmtime() 获取当前时间,struct_time格式,计算机易处理的格式   

            如:time.struct_time(tm_year=2018, tm_mon=9, tm_mday=24, tm_hour=4, tm_min=42, tm_sec=52, tm_wday=0, tm_yday=267, tm_isdst=0)


时间格式化 

strftime()

\"image\"

格式化字符串

\"image\"

\"image\"

striptime() 

\"image\"


程序计时 

perf_counter()

\"image\" 

sleep()

\"image\"

3.5 实例4:文本进度条

问题分析:采用字符串方式打印可以动态变化的文本进度条  能在一行中逐渐变化

刷新的本质:用后打印的字符覆盖之前的字符

print() 默认加换行  print( ,end=””)不换行   r退格到行首

idle不是主要的运行环境 所以r功能在idle屏蔽了 用shell执行

#TextProBar.py
import time
scale = 50
print("执行开始".center(scale//2, "-"))
start = time.perf_counter()
for i in range(scale+1):
        a = '*' * i
        b = '.' * (scale - i)
        c = (i/scale)*100
        dur = time.perf_counter() - start
        print("r{:^3.0f}%[{}->{}]{:.2f}s".format(c,a,b,dur),end='')
        time.sleep(0.1)
print("n"+"执行结束".center(scale//2,'-'))

\"image\"

4.程序的控制结构

4.1 分支结构 

单分支结构

if <条件>:

    <程序1> 


二分支结构

if <条件1>:

        <程序1> 

else:

        <程序2> 


紧凑形式:适用于简单表达式的二分支结构

<表达式1> if <条件> else <表达式2>

如:

guess = eval(input())

print(“猜{}了”.format(“对”if guess == 99 else ”错”)) 


多分支结构

if <条件1>:

    <程序2>

elif <条件2>:

    <程序3

… 

else:

    <程序n>


条件判断>  >=   <   <=    ==   != 

条件组合x and y      x or y     not x


异常处理 

try:

    程序1

except [NameError]:

    程序2

 

try:

    程序1

except:

    程序2

else:

    程序3

finally:

   程序4

4.2 实例5:身体质量指数BMI

问题分析:BMI是身体肥胖程度的刻画(BODY MASS INDEX)  BMI=体重(kg)/身高的平方(m),接收用户信息判断身体肥胖程度

\"image\"

#CalBMI.py
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指标为  国内{},国际{}".format(who,nat))

4.3 循环结构

for 遍历循环

for <循环变量> in <遍历结构>:

    <语句块> 

记数循环

for I in range(5):

    print(i)

 

for I in range(m:n:k):

    print(i)

字符串遍历循环

for c in s:

    <语句块>

 

for c in "Python123":
    print(c)

列表遍历循环ls是列表

for item in ls:

    <语句块>

 

for item in [123,"py",456]:
    print(item,end=',')

文件遍历循环  fi是文件标识符

for line in fi:

   <语句块>


while 无限循环

while <条件>:

   <语句>


循环控制保留字break  continue

 

循环扩展:两种循环后面都可以加else分支  else为没有被break退出是执行的,作为正常运行的奖励  

4.4 模块3:random库使用

random库是使用随机数的python标准库

计算机没法产生真正的随机数,但是可以使用梅森旋转算法产生伪随机数

使用 import random


random库包括2类函数,常用共8个

基本随机数函数:seed(),random()

括展随机数函数:randint(),getrandbits(),uniform(),randrange(),choice(),shuffle()

随机数种子

seed(a=None)    初始化给定的随机数种子,默认为系统当前时间,例:random.seed(10) #产生种子10对应的序列 0.5714025946899135 0.4288890546751146  ..

random()            生成一个[0.0,1.0)之间的随机小数,例:random.random()

为什么要使用随机数种子呢,因为可以使用相同的随机数种子复现程序的执行情况

randint(a,b)        生成一个[a,b]之间的整数,例:random.randint(10,100)

randrange(m,n[,k])    生成一个[m,n)之间以k为步长的随机整数,例:random.random(10,100,10)

getrandbits(k)       生成一个k比特长的随机整数

uniform(a,b)         生成一个[a,b]之间的随机小数

choice(seq)          从序列中随机选择一个元素,例:random.choice([1,2,3,4,5,6])

shuffle(seq)          将序列中元素随机排序,返回打乱后的序列,例:s=[1,2,3,4];random.shuffle(s);print(s)  

4.4 实例6:圆周率计算

#CalPi.py
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):
    x,y = random(),random()
    dist = pow(x**2 + y**2,0.5)
    if dist <=1.0:
        hits = hits + 1
pi = 4 * (hits/DARTS)
print("圆周率是:{}".format(pi))
print("运行时间是:{:.5f}s".format(perf_counter()-start))

\"image_thumb1_thumb\"

蒙特卡罗方法     工程方法

数学思维

计算思维

time库perf_counter来关注程序性能

据统计,程序80%的时间消耗在不到10%的代码上   有点儿类似28法则

关注循环

5.函数和代码复用

5.1 函数的定义与使用

函数定义

函数是一段具有特定功能可复用的语句

df <函数名>(参数):

    <函数体>

    return <返回值>

其中参数可以是0个到多个,是占位符

函数不经过调用是不会执行的 

函数就是IPO的实现

函数也是一段完整代码的封装


函数的参数传递

可选参数传递:可以为参数指定默认值,变为可选参数,可选参数要放在非可选参数之后

\"image\"

可变参数传递:不确定参数有多少个

\"image\"

\"image\"


参数传递的两个方式

默认是按照位置,可以按照名称方式传递

\"image\"


函数的返回值

return可以返回0个或多个结果

函数可以有返回值也可以没有

可以有return 也可以没有

返回多个值的时候是返回元组类型 用() 元素用逗号分隔


局部变量与全局变量

函数外边的是全局变量,里面是局部变量

局部变量是函数内部的占位符,可能与全局变量重名单不相同

函数运行结束后局部变量被释放

规则1:局部变量与全局变量是不同变量

可以使用global保留字在函数内部使用全局变量

\"image\"

规则2:局部变量如果是组合数据类型且未被创建,等同于全局变量    组合数据类型实际是指针的原因

\"image\"

\"image\"


lambda函数

lambda函数返回函数名作为结果

lambda函数是一种匿名函数,没有名字的函数

lambda函数用于定义一种简单的能够在一行内表示的函数

是一种函数的紧凑表达形式

<函数名> = lambda <参数>:<表达式>

f = lambda x,y : x + y

f(10,15)

谨慎使用lambda函数

用于特定的方法的参数

一般就算是1行代码,也建议用def方式定义

5.2 实例7:七段数码管绘制

问题分析:用turtle绘制数码管样式的时间

from turtle import*
from time import*
def drawGap():
    penup()
    fd(5)
def drawLine(draw):              #绘制单段数码管
    drawGap()
    pendown() if draw else penup()
    fd(40)
    drawGap()
    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)
    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)
    left(180)
    penup()
    fd(20)
def drawDate(date):#date为日期,格式约定为 '%Y-%m=%d+'
    pencolor("red")
    for i in date:
        if i == '-':
            write('',font=("Arial",18,"normal"))
            pencolor("green")
            fd(40)
        elif i == '=':
            write('',font=("Arial",18,"normal"))
            pencolor("blue")
            fd(40)
        elif i == '+':
            write('',font=("Arial",18,"normal"))
        else:
            drawDigit(eval(i))
def main():
    setup(800,350,200,200)
    penup()
    fd(-300)
    pensize(5)
    drawDate(strftime('%Y-%m=%d+',gmtime()))
    hideturtle()
    done()
main()

结果:

\"image\"

5.3 代码复用与函数递归

代码复用

代码抽象化:使用函数等方法对代码赋予更高级别的定义

函数对象是代码复用的2中主要形式

函数是在代码层面建立了初步抽象

对象有属性和方法,是更高级别的抽象

封装


模块化设计

分而治之:

通过函数或对象封装将程序划分为模块与模块间的表达

主程序、子程序与子程序之间的关系

一般将子程序看作模块,主程序看作模块与模块间的关系

是一种分而治之、分层抽象、体系化的设计思想

紧耦合:两个部分之间交流很多,无法独立存在

松耦合:两个部分之间交流很少,可以独立存在,有各自清晰简单的接口

模块化设计基本思路和原则:模块内部紧耦合,模块之间松耦合


函数递归:函数定义中调用自身的方式

两个关键特征

链条:计算过程存在递归链条

基例:存在一个或者多个不需要再次递归的基例  递归的最末段

类似数学归纳法,先证明第一个取值命题成立,然后第n个取值命题成立,第n+1取值命题也成立,那么命题成立

递归可以理解为数学归纳法思维在编程中的体现


函数递归的调用

\"image\"

函数+分支语句   :基例和链条分别编写代码

3个小栗子

\"image\"

\"image\"

\"image\"

\"image\"

5.4 模块4:Pyinstaller库的使用

是第三方库 需要安装

pip工具

shell中使用使用             pyinstaller –F <文件名.py>

\"image\"

\"image\"

5.5 实例8:科赫雪花小包裹

\"image\"

\"image\"

\"image\"

收藏 打印
您的足迹: