Python MOOC 笔记
博客说明
- 本文为MOOC上的python语言程序设计课程笔记,结合自己写c++的一些比较,仅个人所见,不一定全,也不保证没有错误,欢迎指正。
- 本文只是自己写来记录记录学习过程,会持续更新至结束并可能自己拓展一些东西。
- 本文也不适合入门者参考,因为我是以一个c++转python的身份写的,一些东西略去了,python入门学习建议观看MOOC原视频。
- 因为是第一篇markdown写的文章,格式语法等可能尚有不足。
课程定位与绪论
- 在线课程:MOOC
- 在线实践:https://python123.io
- 课程安排
第一章——python的基本语法元素
1.程序设计基本方法
- 语言类型
2.程序编写方法
IPO:
六步:
2.python开发环境配置
3.实例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("输入格式错误")
4.python程序语法元素分析(基于温度转换实例)
- python注释:
#
表示单行注释;
'''
三个单引号括起来的表示段落注释'''
- python缩进:
python执行严格缩进表示层次(不像c++使用{}
) - python命名:
python变量命名与c++类似,但是可以用中文!python大小写敏感,所以虽然if
是关键字但是IF却可以用作变量名 - python数据类型:
整数、浮点、字符串与c++类似,但有个列表类型,用[]
括起来,逗号隔开;字符串用单引号或者双引号都行 - python数组编号:
一个是正向递增序号,比如数组索引,和c++一样;
一个是反向递减序号,最后一个元素为-1,往前依次递减 - python索引与切片:
<字符串>[M]返回字符串中M号字符;
<字符串>[M:N]返回字符串中M号到N号(不含N号)字符,类似matlab里的用法 - 关键字
in
:
表示是否在一个列表中,返回逻辑值。 - 分支语句:
if
条件:注意条件语句中条件后要加冒号;
else if在python里是elif
- 简单常用函数:input(),print(),eval()
- print()函数的格式化:
print(“转换后的温度是{:.2f}C”.format©)——{}
表示槽,format中的后续变量将以指定格式填充到这个槽里面; print另有逗号输出 - eval()函数:
评估函数:将参数最外侧的引号去掉执行剩余语句,比如数字字符串去掉引号就成了相应数字类型,比如用一个字符串表示的命令,去掉引号就成了python可执行命令。 如eval(‘print(“Hello”)’)会去掉参数外侧引号剩下print(“Hello”),这是一个可执行的python语句——eval()函数是个很有意思的函数,可以在运行时由用户给出执行的函数
第二章——python基本图形绘制
1.深入理解python语言
- 计算机技术的演进(略)
- 程序语言的江湖(略)
- python的特点
- 强制可读
- 较少底层元素
- 多种编程方式
- 支持中文字符
- 大量且快速增长的库
- 跨平台
2.python蟒蛇绘制
看看代码:
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()
3.turtle库的函数全解
4.turtle程序语法元素分析
- import引用库:
其实就像c++里的#include<>包一样:
import <库名>
from <库名> import <函数名>
from <库名> import *
import <库名> as <库别名> - 循环语句:
for <变量> in range()
range函数产生序列
range(N)产生0-N-1的序列
range(M,N)产生M到N-1的序列
第三章——基本数据类型
1.数字类型及操作
整数,浮点数,复数,基本和c++差不多(多个复数类型),区别如下:
- 整数对应数学中的整数,可正可负且没有范围限制,不同于c++中有signed unsigned区别以及short,int,long区别
- 浮点数对应数学中的实数,如c++中一样有尾数误差
- 数值运算符与c++基本一样,但几点注意:
/
是除法运算,且不会出现整数除整数还是整数丢失精度的问题,因为python另有一个//
整数除符号,如10//3=3,10/3=3.33333333- 另外有
**
运算符,表冥运算,和pow一样; - python也有增强赋值运算符如
+=
,**=
等;
- 常用函数也与c++差不多:pow,round等。
函数 | 说明 |
---|---|
pow(x,y,z) | x^y%z |
round(x,n) | 将x四舍五入到n位小数 |
- python类型转换(可以直接在类型之间转换)
示例 | 结果 |
---|---|
int(123.3) | 123 |
int(‘123’) | 123 |
2.字符串类型及操作
字符串的表示,操作符,处理函数,方法,格式化:
- 字符串表示:
有以上多种字符串表示法可以使在字符串中使用单、双引号更简单:字符串中有单引号那么用双引号括起来;字符串中有双引号用单引号括起来;两者都有用三单引号括起来
- 字符创编号与切片:
- 字符串编号为从左往右由0递增或是从右往左由-1递减
- 字符串切片:
用法 | 意义 |
---|---|
str[M:N] | str中M到N-1号元素 |
str[:N] | str中第一个到N-1号元素 |
str[M:] | str中M号到最后一号元素 |
str[M:N:i] | str中M到N-1号元素,每次步进i |
str[::-1] | str中由最后一个元素到第一个 |
- 转义字符——python中也有转义字符\
- 字符串操作:
操作 | 意义 |
---|---|
x+y | 将x,y两个字符串连接 |
x*n或n*x | 将x字符串复制n遍 |
x in s | 判断x是否在s中(即是否为其子串) |
- 字符串八个常用方法:
方法 | 意义 |
---|---|
str.lower() | 将str转换成小写 |
str.upper() | 将str转换成大写 |
str.split(sep=None) | 将str按sep字符分割 |
str.count(sub) | 求sub子串在str中出现次数 |
str.replace(old,new) | 将str中old子串替换成new |
str.center(width[,fillchar]) | 字符串按宽度width居中且以fillchar填充两边 |
str.strip(chars) | 将字符串两端的chars字符(们)去掉 |
str.join(iter) | 将str插入到iter的每个元素之间,用于字符串分隔 |
- 字符串操作函数:
函数 | 意义 |
---|---|
len(x) | 计算字符串长度,中文字符也算一个 |
hex(x),oct(x) | 将整数x转换成十六进制或八进制的字符串形式 |
chr(x) | 将unicode x转换成对应字符 |
ord(x) | 将字符x转成unicode |
- 字符串格式化
字符串中的{}表示占位槽,.format()函数中的参数填进槽中,{}中可使用如下格式参数限制输出数据格式:
格式参数(按顺序) | 参数意义 | |
---|---|---|
填充 | 表示未填满的位置使用的填充符号 | |
对齐 | 表示对齐方式,<左对齐,>右对齐,^居中对齐 | |
宽度 | 表示输出数据占据位置宽度 | |
千分位符号 | 表示输出数千分位符号,","或者没有 | |
精度 | 表示输出数精度,保留小数位数 | |
类型 | 表示输出数类型b,c,d,e,f,%等 |
例子:
"{0:*<10,.3f}".format(6225.3738)
输出:
'6,225.374****'
3.time库的使用
- 作用
- 计算机时间的表达
- 提供获取系统时间并格式化输出功能
- 提供系统级精确计时,用于程序性能分析
- 使用
import time
time.<b>()#调用相关函数
- 函数类别
类别 | 例子 |
---|---|
时间获取 | time(),ctime(),gmtime |
时间格式化 | strftime(),strptime |
程序计时 | sleep(),perf_counter() |
- 函数介绍
函数 | 描述 |
---|---|
time() | 返回当前时间浮点数 |
ctime() | 返回当前时间字符串 |
gmtime() | 获取当前时间结构体 |
strftime(tpl,ts) | 将gmtime()获取的时间ts换成tpl模板指定的字符串如:time.strftime(’%Y-%m-%d %H:%M:%S",t) |
strptime(ts,tpl) | 与strftime相反,strptime将时间字符串转换成时间结构 |
perf_counter() | 返回一个CPU级别精确的时间计数值,单位秒,一个 步骤前后两次perf_counter()然后时间值相减可计时 |
sleep(s) | 程序休眠s秒 |
perf_counter用例:
start=time.perf_counter()
#do something here
end=time.perf_counter()
end-start#operation duration
- time库的时间格式控制符
格式化字符串 | 日期/时间说明 | 值范围和实例 |
---|---|---|
%Y | 年份 | 0000~9999,例如:1900 |
%m | 月份 | 01~12,例如:10 |
%B | 月份名称 | January~December,例如:April |
%b | 月份名称缩写 | Jan~Dec,例如:Apr |
%d | 日期 | 01~31,例如:25 |
%A | 星期 | Monday~Sunday,例如:Wednesday |
%a | 星期缩写 | Mon~Sun,例如:Wed |
%H | 小时(24时制) | 00~23,例如:12 |
%h | 小时(12时制) | 01~12,例如:7 |
%p | 上下午 | AM,PM |
%M | 分钟 | 00~59 |
%S | 秒 | 00~59 |
4.文本进度条实例
废话不多讲,上代码:
#TextProBarV1.py
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))
time.sleep(0.5)
print("执行结果")
这样的代码虽然每一行都输出进度,但是怎么控制单行输出进度呢?即这里需要控制print函数使其不换行(print函数默认换行),每次都在原位更新进度。
#TextProBarV1.py
import time
scale=10
print("------执行开始------")
for i in range(scale+1):
a='*'*i
b='.'*(scale-i)
c=(i/scale)*100
print("\r{:^3.0f}%[{}->{}]".format(c,a,b),end='')
time.sleep(0.5)
print("执行结果")
print函数中end
的参数给定分隔符,默认的是换行,这里设为空就不换行,前面的\r
表示回车。但是如果在IDLE中运行时不会原位刷新,因为IDLE中屏蔽了\r
功能,所以应该在cmd或类似的环境中运行。
**提示:**有趣的是c++中也有
\r
功能,之前一直不知道。它表示回到行首,这样就可以原位输出。但是如果输出的字符串不如原来的长的话是不能完全覆盖的,也就是边输出边覆盖而不是先把原来的删除再输出.
第四章——程序的控制结构
1.程序分支结构
- 单分支结构
if <条件句>:
<表达式>
结构图如下:
- 二分支结构
- 一般语法如下:
if <条件>:
<语句1>
else:
<语句2> - 还有一种紧凑形式
<表达式1> if <条件> else <表达式2>
- 一般语法如下:
**注意:**紧凑形式不支持带
=
的赋值语句,仅支持简单表达式
结构图如下:
- 多分支结构
语法如下:
if <条件1>:
<语句1>
elif <条件2>:
<语句2>
…
else:
<语句n>
结构图如下:
- 条件组合与关系运算
关系运算符>
,>=
,<
,<=
,==
,!=
等与c++一致,但是python可支持连续比较,比如1<2<3输出true
;逻辑运算符有and
,or
,not
等 - 异常处理
- 一般用法:
try:
<语句块1>
except:
<语句块2> - 指定异常类型:
try:
<语句块1>
except <异常类型>:
<语句块2> - 更高级用法:
try:
<语句块1>
except:
<语句块2>
else:
<语句块3> #else语句块在不发生异常时执行
finally:
<语句块4> #finally语句块一定执行
- 一般用法:
2.BMI实例
很简单的代码,主要就是处理分支语句,根据BMI1判定胖瘦,略
3.程序循环结构
- 遍历循环
for <循环变量> in <遍历结构>:
<语句块1>
**注意:**遍历循环除了可以计数循环,还能遍历字符串循环、遍历文件循环,甚至可以对元组、列表、字典遍历循环,反正只要后边的遍历结构包含了多个元素,都可以遍历循环
-
无限循环
while <条件>:
<语句>
-
循环控制保留字
break
continue
-
循环的高级用法
for <变量> in <遍历结构>:
<语句块1>
else:
<语句块2>while <条件>:
<语句块1>
else:
<语句块2>
以上else
与异常处理里面的else
相似,表示循环没有遇到break
时执行
4.random库的使用
random是用于生成随机数的标准库,使用梅森旋转算法生成伪随机数。
给个实例,清晰明了:
import random
random.seed(10)#设置种子,不设的话是系统时间,最好不设
random.random()#产生0到1的随机小数
random.randomint(1,10)#生成1到10之间的随机整数
random.randomrange(20,100,10)#生成20到100之间以10为步长的随机整数,第三个参数可不给
random.getrandbits(16)#生成一个16比特长的随机整数
random.uniform(10,100)#生成10到100的随机小数
s=[1,2,3,4,5,6,7,8,9]
random.choice(s)#在给出序列中随机选取一个数
random.shuffle(s)#将列表s随机打乱
5.圆周率实例
用了个蒙特卡洛法求圆周率2,很简单,不过有几个小点注意下:
- python代码换行,末尾加个
\
就可换行,就像matlab中末尾加个...
换行一样 - 多赋值。比如x,y=random(),random(),再比如a,b=eval(input()),eval(input())
第五章——函数和代码复用
1.函数的定义和使用
-
函数的理解与使用
语法如下:
def <函数名>(<参数列表>):
<函数体>
return <返回值>
-
函数使用及调用过程
略。与c++一样,编程语言都差不多。
-
函数的参数传递
与c++法则一样。同样地:
-
可给定可选参数,可选参数在非可选参数后面,如:
def fact(n,m=1): s=1 for i in range(1,n+1): s*=i return s//m
-
可给定可变参数,用
*
表示,不确定参数放最后,只能有一个(因为不确定参数可以表示任意多个),如下:def fact(n,*b): s=1 for i in range(1,n+1): s*=i for item in b: s*=item return s #使用 fact(10,3)#可变参数为一个 fact(10,3,5,8)#可变参数为3个
-
参数传递有两种方式,按顺序传递与按名称方式传递。
-
-
函数的返回值
-
函数可以没有返回值,甚至可以没有
return
关键字 -
函数可以返回一个返回值也可以返回多个,返回多个时各个值用逗号隔开,如:
def fact(n,m=1): s=1 for i in range(1,n+1): s*=i; return s//m,n,m
-
接收多个返回值时可用多赋值,即赋值号前多个变量,用逗号隔开,如:
a,b,c=fact(10,5) print(a,b,c)
-
-
局部变量与全局变量
-
生存期与作用域不同,参考c++
-
可用global关键字声明变量为全局变量(这个全局变量必须定义过了,所以一般放在函数前面定义,在函数里面再声明为全局,如:
times=0 def fact(n): global times#声明times是个全局变量,否则会生成局部变量覆盖上面的那个变量 times+=1 s=1 for i in range(1,n+1): s*=i return s
-
局部变量为组合数据类型且未在函数内部真实创建时,等同于全局变量,如:
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) return func("C") print(ls) #输出为:['F','f']
python中组合类型是由指针体现的,如果没有在函数中真实创建给组合类型,那么是通过指针操作全局变量
-
-
lambda函数
lambda是一种匿名函数显然,使用lambda保留字定义,以函数名为返回结果,是一种单行函数紧凑表达形式,语法如下:
<函数名>=lambda <参数>:<表达式>
相当于:
def <函数名>(<参数>):
<函数体>
return <返回值>
不一样的是只能使用表达式做返回值,没有复杂的函数体语句,如:
f=lambda x,y:x+y f(10,15) #输出为:25 #定义无参的 f=lambda :"lambda函数" print(f()) #输出:lambda函数
2.七段数码管绘制实例
主要理解
- 模块思维:确定模块接口,封装功能
- 规则化思维
- 化繁为简思维
代码如下:
#七段数码管绘制
import turtle,time
def drawGap():
turtle.penup()
turtle.fd(5)
def drawLine(draw):
drawGap()
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,5,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):#date 日期格式为:'%Y-%m=%d+'
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(-300)
turtle.pensize(5)
drawDate(time.strftime('%Y-%m=%d+',time.gmtime()))
turtle.hideturtle()
turtle.done()
3.代码复用与函数递归
-
模块化设计
- 紧耦合:两个部分之间交流很多,无法独立存在
- 松耦合:两个部分之间交流较少,可以独立存在
- 模块内部紧耦合,模块之间松耦合
-
函数递归思想——基例,链条,数学归纳法等(略)
-
递归调用过程(略)
-
有一个有趣的问题:
python中最多能递归多少层次呢?我们知道在c++中函数调用是在栈上的,所以递归深度太深会导致栈溢出,那么python是不是呢?经过测试,python也是会溢出的,比如一个简单的求阶乘函数,发现递归994次时超出最大递归深度,这个函数中是没有临时变量的,也就是单纯保存函数地址溢出了:
def fact(n): if n==1: return 1 else: return n*fact(n-1) fact(993)#运行成功 fact(994)#运行出错
4.PyInstaller库的使用
5.科赫雪花实例
第N章——自己总结的想更就更的几点
1.python与c++的交互
- python调用c++的可执行程序
代码示例如下,其实很简单:
import os
os.system("cmd")#可以直接执行命令调用exe
os.system('xxx.exe')#比如也可以这样运行c++生成的exe文件
- python调用c++的库
- python,c++交叉编程