本来想学计算机的一些基础知识的,结果这个直接讲到Python了,先去学C再来学Python,笔记先放这儿,学完c接着学。
第一章。计算工具与计算思维。
1.1计算工具的历史
老师推荐两本书
《计算机简史》2020年四月第三版,可以了解计算机的历史
《计算机技术发展史》国防科技大学教授胡守仁
1.2计算思维概述
1.3计算的自动化
完成计算的关键环节
一是记录下参与运算的数
二是应用完成计算的规则
算法:求解问题的计算步骤或方法
程序:用计算机可以理解的语言来描述的算法
1.4计算的抽象
阿兰图灵:计算机科学之父
图灵机的设想使得通用计算成为了可能。
图灵机的结构
一条两头可无限延伸的纸带
纸带被划分为一个个的小方格,方格中可包含有限非空符号集中的任意符号也可为空
一个读写头
读写头可以向左或向右移到相邻方格
一个控制器
控制状态转移规则
第二章 开启Python之旅
print函数
使用print(…) 函数,该函数的功能是命令计算机打印括号中的内容,在 Python 中,Hello World!是一个字符串,也就是一串字符。字符串要用引号括起来,可以是单引号、双引号或者三引号(三个单引号),例如下面三条语句功能等价:
print('Hello World!')
print("Hello World!")
print('''Hello World!''')
注释
现在要开始写一个新的程序了,可以把之前的语句删掉重新写新程序,也可以使用注释的方式,方法是在要注释的内容前面加上#,例如:
#print('Hello World!')
注释的作用一般用于添加说明性的文字,如解释某行代码是什么意思,从而提高代码的可读性。
表达式
print('1+1')并不能打印出结果2,而是打印1+1,这是因为引号括起来的是一个字符串,而print处理字符串的方式就是把引号里面的内容直接打印出来。如果要打印运算结果 2,只要把引号去掉。
print(1+1)
去掉引号后,1+1不再是一个字符串,而是一个表达式,print函数处理表达式的方式是先计算表达式的值再打印计算结果,这样就能打印出 1+1 的结果 2。
Python 中一些常见的运算符:
+、-、*、/、**
分别表示加、减、乘、除、乘方(例:6**2表示 62、6**0.5表 示 6),利用这些运算符,就可以完成很多计算。
例题
计算和打印阴影部分的面积 S
将正方形的面积减去内切圆的面积即可得到 S,对应的程序是:
print(2.2**2-3.14*(2.2/2)**2)
在写表达式的时候,要注意运算的优先级,在表达式中,不管几层括号,都用圆括号表示,而不使用方括号和花括号,方括号、花括号有其它用途。
但是直接对数字进行计算会存在一些不便,例如: 1)不便于编写,公式中每个参数的值是什么,编写程序时需要临时查阅; 2)不便于阅读,代码中每个数值代表什么意思,不够直观; 3)不便于修改,例如现要改成计算 5.5 秒时的坐标,需对多处进行修改,如有遗漏,则会导致错误的计算结果。 如果能像数学公式中一样,给这些数字“取名字”,就能比较好的解决以上问题
赋值
给数字“取名字”的过程称为赋值,“名字”称为变量,例如下面程序第 1 行可以理解为给数字 3.14 取了个名字叫做pi,后面在使用时就可以用变量pi来代替 3.14 (如第 2 行)。pi = 3.14称为赋值表达式,=不叫等号而叫赋值符。赋值语句的运行过程是先计算赋值符右边的值,再把这个值赋给左边的变量。
pi = 3.14
S2 = pi*(2.2/2)**2
print(S2)
赋值符的右边也可以是一个更复杂的表达式
变量的命名
变量的名字不是随便取的,需要遵守一些规则,主要包括: 1)可包含大写字母、小写字母、数字、下划线,但不能以数字开头,例如,v0、V_0、_V0_、_0V_都是合法的变量名,而0v、v0*则不是(前者以数字开头,后者包含非法符号*); 2)变量名区分大小写,例如,v0和V0是两个不同的变量名; 3)一般不使用 Python 已用的名字,例如,print已被使用(打印),给变量取名时一般不取成print; 4)尽量取有意义的名字,例如,3.14 取名叫pi,与圆周率符号 π 一致,而不叫alpha或者x,这样不便于阅读和使用。
例题
利用赋值的方法,计算和打印阴影部分的面积 S(正确结果是 1.0406):
参考程序如下:
a = 2.2 #边长
pi = 3.14 #圆周率
S1=a**2 #正方形面积
S2=pi*(a/2)**2 #圆的面积
S=S1-S2 #阴影面积
print(S) #打印
注:有时也可以把多个赋值语句合并成一条语句,如第 1、2 行可合并成一行a, pi = 2.2, 3.14, 它表示的意思是把后面两个值分别赋给前面两个变量,这叫做多重赋值。 将上面的程序与上关例题的程序进行对比:
print(2.2**2-3.14*(2.2/2)**2)
虽然代码行数增加了,但程序在编写、阅读、修改时更加方便。
上关计算出了 3.5 秒时的坐标,也就是说在编写程序的时候就已经知道 t 是等于 3.5 了。但有些时候,一些变量的值在写程序的时候并不能确定,比如要让程序计算某一个时刻的坐标,这时 t 的值在写程序的时候是不确定的,要在程序运行的时候由用户告诉程序 t 到底等于多少。 这种情况很常见,比如用 Windows 的计算器算一个加法,加数和被加数的值是什么,在程序员开发计算器的时候无法知道,要在使用过程中由用户输入。
本关的任务就是要计算时刻 t 的炸弹坐标,t 的值不是在代码中设定,而是在运行时获取。
相关知识
input函数
获取运行时的输入可以使用input函数,尝试如下程序:
t=input('t=')
print('获取的t为:', t)
注1:若在自己的 Python 环境中运行上面的程序,需在输出的t=后面通过键盘键入一个值,然后再按回车,程序才会继续执行,此过程程序即捕获了键盘输入的内容。
注2:若在右边编程界面中运行该程序,则系统会在程序运行时自动输入,不需通过键盘键入。另外,可以先将右边编程窗口中的初始代码删除,然后再试验上面的程序,在编写过关程序时,再通过右上角的“恢复初始代码”按钮还原初始代码。 第 1 行的的功能是获取输入的 t 值,执行过程可以理解成三个步骤:打印括号里面的提示文字,获取输入,将获取的值赋给变量t。第 2 行再把t的值打印出来。
再试一下下面的程序:
t=input('t=')
print('获取的t为:', t)
print('此时纵坐标为:', 3000-1/2*9.8*t**2)
此程序会报错,错误指向第 3 行,报错信息是unsupported operand type(s) for ** or pow(): 'str' and 'int'(不支持字符串与整数之间的**运算)。之所以会出现此问题,是因为input函数获取的输入是字符串类型的,所以获取的t 值是字符串(如'3.5'),而字符串类型不能进行平方运算(如'3.5'**2),故而报错,这就好比'hello world'**2运算无法进行。 要解决这个问题,就需要了解一下数据类型和类型转换。
数据类型
在 Python 里面,每个对象都有一个类型,比如'Hello World!'是字符串(用 str表示),3000是整型(用int表示,对应了数学里面的整数),3.14是浮点型(用float表示,对应了数学里面的实数),等等。
利用type函数可以查看一个对象的数据类型,例如:
print(type('Hello World!'))
print(type(3000))
print(type(3.5))
通过此方法可以查看input获取的t的类型:
t=input('t=')
print('t的类型是:', type(t))
类型转换
不同的类型之间有时候是可以相互转换的,例如float函数是将某种类型转换成浮点型,如float('3.5')是将字符串'3.5'转换成浮点数3.5。
t = float('3.5')
print('t的类型是:', type(t))
类似地,int函数是转换为整型、str函数是转换成字符串,等等。
此外,还有一个函数也可以实现类型转换的功能,就是eval函数,这个函数的功能是对字符串表达式进行计算,例如, 它可以将字符串 '1+1' 看作数学表达式 1+1,并计算出结果 2。
a = eval('1+1')
print(a)
print(type(a))
一个值也可以构成表达式,比如3000、3.5,其计算结果就是本身。所以eval函数也可以处理,从而就间接实现了类型转换的功能,比如,eval('3000')是把字符串'3000'转换成整型 3000,eval('3.5')是把字符串'3.5'转换成浮点型3.5。
例题
修改如下程序,使其能正确计算 t 时刻的纵坐标。
t=input()
print('获取的t为:', t)
print('此时纵坐标为:', 3000-1/2*9.8*t**2)
前面提到,该程序的问题在于t的类型为字符串,在进行乘方运算时出错。改正的方法是在读取t后将其转换为浮点型,此处可以使用float或eval函数,使用 eval函数的代码如下:
t=eval(input()) #在此行进行类型转换
print('获取的t为:', t)
print('此时纵坐标为:', 3000-1/2*9.8*t**2)
Python库
要实现绘制功能,需要用到 Python 库,那什么是库呢?可以这样来理解。 在基本的 Python 里面只提供了一些最基本的功能,比如加减乘除等。但很多时候需要使用更高级的功能,比如求三角函数,而 Python 里面并没有直接提供这些功能。从理论上来说,这些高级功能可以通过基本功能来实现,比如三角函数可以转换成加减乘除运算,但这样很麻烦,而且这些高级功能很多人都要用。 所以就有人提前用 Python 的基本功能实现了这些更高级的功能,并把这些功能打包取个名字,提供给别人用,这些包就是 Python 库。这样的话,当我们要用一些高级功能,比如三角函数,就只要调用这些库里面的功能,而不用自己写代码实现,从而简化了编程的难度。 Python 的一个显著优点就是拥有十分丰富的库,很多高级功能都可以通过调用库来实现,而不用自己写代码。
库的使用
使用 Python库 的步骤可以大概分为以下步骤。 1)确定要使用的库,一方面本课程会介绍一些,如 math 库(里面提供了很多数学运算,如三角函数),而更多的时候需要自己在网上搜索; 2)若 Python 环境中不包含该库,则需要先安装; 3)在程序中导入库,用到的语句是import,比如导入 math 库是 import math; 4)使用库中的功能,如 math.cos(3) 是使用 math 库中的余弦函数cos求 cos(3) 的值。
math库示例
下面的程序是计算 cos(π):
import math #导入math库
a=math.cos(math.pi) #调用math中的对象求余弦
print(a) #打印计算结果
该程序先导入 math 库,然后调用 math 里面的cos函数求余弦,π 值可以写3.14159,也可以直接调用 math 库里面定义的更精确的pi,计算完的值赋给变量a,最后再打印a的值。 有些时候,库的名字很长,在使用的时候如果每次都把库的名字完整写出来,会比较麻烦,这时候可以给库取个别名,如下程序给math重新取名叫m(第 1 行),在使用的时候就只要写m(第 2 行),而不用写math,更加方便。
import math as m #取别名
a=m.cos(m.pi) #使用别名
print(a)
还有些时候,可能只要用一个库里面少数几个功能,那就可以采用from … import …的方式,例如下面的程序从 math 库里面导入cos和pi这两个功能(第 1 行),在使用cos和pi的时候就不用再写出库的名字(第 2 行)。
from math import cos, pi #从math中导入cos和pi
a=cos(pi) #直接使用cos和pi,不用再加math.
print(a)
还有一种极端的情况,from … import *,例如如下程序先从 math 库导入所有功能(第 1 行),后面就可以直接使用 math 库里面的各种功能了(第 2 行)。
from math import * #从math中导入所有对象
a=cos(pi) #直接使用cos和pi,不用再加math.
print(a)
但是,一般不推荐使用后面两种方式,因为可能带来命名混乱的问题。例如,如果你的程序里面也定义了一个变量叫做pi,这个pi就会和 math 库里面的pi同名,在使用的时候,到底用的是哪个pi,有时候就会分不清。而前面两种方式,pi前面会加上库的名字,就可以和自己定义的pi区分开来。 附:math 库使用手册。
例题
利用 matplotlib.pyplot 库可以实现图形绘制,尝试如下代码:
import matplotlib.pyplot as plt #导入库
xt, yt = 1, 2 #设置坐标值
plt.plot(xt,yt,'ro') #绘制坐标点(xt,yt)
plt.show() #显示图像
该程序的功能是在坐标系中绘制一个点,点的坐标是 (1,2),每行解释如下: 第 1 行:导入库,因名字太长,取别名为plt; 第 2 行:设置要绘制的点的坐标值; 第 3 行:利用plot函数进行绘制,xt和yt是坐标值,这个'ro'是设置坐标点的格式,r表示点的颜色是红色(改为b就是蓝色,改成y就是黄色,等等),o表示点的形状是圆形(改为v就是三角形,改为*就是星形,等等); 第 4 行:将绘制的图形显示出来。 在这个基础上可以再进行一些设置,如:
import matplotlib.pyplot as plt
xt, yt = 1, 2
plt.plot(xt,yt,'ro')
plt.grid('on') #显示网格线
plt.axis([0,2,1,3]) #设置坐标轴范围
plt.show()
注:如在右侧编程界面尝试示例代码,可将 Begin-End 区间的初始代码删除(保留最后两行代码),再将示例代码贴入 Begin-End 区间,点击“评测”按钮即可看到运行结果。
第 4 行是显示网格线,第 5 行是设置坐标轴范围(横坐标范围是 [0,2],纵坐标范围是 [1,3])。
调试功能
利用调试功能可以跟踪程序的执行过程
有时if else也可以只使用if分支