万事俱备了,马上就可以磨刀霍霍向 Python 了。那如何开始呢,再回到开篇介绍的“编程本色”中,将几个问题的解决思路拿到此处,开启编程之旅。
1. 问题回顾
1.1 数学问题
- 求和(n 为偶数,n >= 1)
- 拿出一个本子或者一张纸,一支笔,准备开干
- 写上问题描述信息,自己的姓名,时间等信息
- 询问提问者 n 的值为多少(如:n = 10)
- 计算 1 - 1/2 = 1/2
- 计算 1/2 + 1/3 = 5/6
- 依次类型,追个向下计算
- 计算出最终的结果,并将最终结果告诉提问者
1.2 生活问题
- 根据江苏省最新个税法,根据员工薪资,计算个人所得税及税后收入
2. 进入编程世界
2.1 思维步骤
- 创建一个目录(包),进入目录中创建一个以 .py 结尾的文本文件(模块),打开文件准备开干(写代码)
- 写上一些信息,用于说明该文件的用途、作者、时间的信息(注释)
- 提示用户输入 n 数值(input),并将这个值暂存下来,标识为 n (变量),以备后续使用
- 第一次计算,将 1 - 1/2 的结果存下来,标识为 s1 (变量),以被下一步使用
- 第二次计算,将上一步的结果 s1 + 1/3 的结果存下来,标识为 s2 (变量),以被下一步使用
- 重复上面的步骤,直到第 n 次计算,将上一步的结果 sn-1 + 1/n 的结果存下来,标识为 sn
- 输出最终的计算结果 sn
2.2 术语解释
- 用于组织代码文件的目录,在小 Python 的世界里,叫做包(或叫模块)
- 用于存放具体的代码的文件,在小 Python 的世界里,也叫做模块(或叫 Python 文件)
- 用于说明代码用途,只给人类看的说明性描述,在小 Python 的世界里,叫做注释
- 为了接收用户的输入,小 Python 提供了一个
input(提示信息)
来完成 - 为了能够将一些数据信息存储到计算机中,而且又能被后续继续再次使用,就需要引入一个标识,这个叫做标识叫做
变量
。在程序中,可以通过变量再次找到其所指向的数据内容,但变量所指向的数据内容可能并不能通过变量本身看的出来,它只是一个标识。 - 能够完成数据与数据之间运算操作的连接符号(如此处的
+
和-
),叫做运算符
- 为了能够将最终计算结果输出,在小 Python 那提供了一个 print() 来完成
2.3 程序代码
'''
文件名:summation.py
用途:计算 1 - 1/2 + 1/3 - 1/4 + ... + 1/n-1 + 1/n
作者:Mr.潘
时间:2020-07-23
'''
# 询问用户输入 n 的数值,如果 n = 10
n = input("请输入 n 的数值:")
# 第一次计算
s1 = 1 - 1/2
# 第二次计算
s2 = s1 + 1/3
# 第三次计算
s3 = s2 - 1/4
# 第四次计算
s4 = s3 + 1/5
# 第五次计算
s5 = s4 - 1/6
# 第六次计算
s6 = s5 + 1/7
# 第七次计算
s7 = s6 - 1/8
# 第八次计算
s8 = s7 + 1/9
# 第九次计算
s9 = s8 - 1/10
# 输出最后的计算结果
print(s9)
3. 程序的核心部件
3.1 注释
对于注释这个东西,程序员总喜欢做一个不写注释的人,但期望读有注释的代码,本人也是这号人中的一位。但无论是从代码的可读性,还是从代码的可维护角度考虑,注释都是个必不可少。所以,我克服自己的懒惰,写注释,写博客,散发一些正向引导。
每种语言都会有注释这个部件,但表现形式可能略有差别。对于小 Python 而言,其注释主要分为两种,一种叫单行注释,一种叫多行注释/文档注释。
**单行注释:**以 #
开头,#
右边的所有东西都被当做说明文字,而不是真正要执行的程序,只起到辅助说明作用。
# 打印功能,独立成行的注释
print("小 Python,你好。") # 打印功能(为了保证代码的可读性,注释和代码之间至少要有两个空格)
多行注释/文档注释:使用三个双引号或单引号来注释多行内容,如果希望编写的 注释信息很多,一行无法显示,就可以使用多行注释,一般用于代码模块的说明,函数说明,类说明等等,这些概念后面会陆续蹦跶出来。
'''
单引号进行多行注释
'''
"""
双引号进行多行注释
"""
3.2 字面量
这个概念,一般通过望文生意即可理解,所谓 字面量
所表示的意思就是它的字面的值,在程序中可以直接使用字面量,也可以理解为数学中的已知数。如:10, 520, 1024, 512, 3.14, 0.68, 3 + 5j, "小 Python"
等等,一眼就能望穿你是什么数据。
3.3 数据类型
如果让你给上面的 字面量
分分类,对聪明如我的你来说,应该是小菜一碟。
高层分类:
数值:10, 520, 1024, 512, 3.14, 0.68, 3 + 5j
文本:"小 Python",真,假
精准分类:
整数:10, 520, 1024, 512
小数:3.14, 0.68
复数:3 + 5j
布尔:True, False
文本:"小 Python"
非常好,这个分类你应该认同吧。对应到编程世界,其实是几乎相同的,我想这就是源于生活,再应用于生活。暂且我们值需要了解这么几种基本数据类型即可,后续类型再慢慢来,再用小 Python 的口吻说明下:
类型 | 描述 | 示例 |
---|---|---|
int(整型) | 无小数部分的数 | 512, 520, 999, 1024 |
float(浮点型) | 有小数部分的数 | 3.14, 0.68 |
complex(复数) | 实数(整数或浮点数)与虚数的和 | 3j, 3 + 5j |
bool(布尔) | 逻辑值 | True, False |
str(字符串) | 单引号: '允许包含有 "双" 引号' 双引号: "允许包含有 '单' 引号" 三重引号: '''三重单引号''', """三重双引号""" | "小 Python", 'Mr.潘', """吃喝玩乐""", '''唐诗宋词''' |
3.4 数据类型转换
写到这个主题,我头脑中浮现了“变性”这个词,通过某种技术可以改变事物的属种,比如:将男变成了女,当然也有失败的风险,就会变成了“人妖”。
在编程的世界里,如果想对数据做“变性(从一种类型转变成另一种类型)”的操作该如何实现呢?
转 int 类型:将长得像整数的数据转换为 int 类型
int("1024") # 输出整数 1024
int(3.14) # 长得不像整数,但属于数值类型,输出整数 3
int(True) # 长得不像整数,但 True 和 False 本质上是属于整数类型的,输出整数 1
int("3.14") # 变性失败,长得不像整数,又不属于数值类型
int("102U") # 变性失败,长得不像整数
转 float 类型:
float("3.14") # 输出浮点数 3.14
float(512) # 输出浮点数 512.0
float(False) # 长得不像小数,但 True 和 False 本质上是属于整数类型的,输出整数 0.0
float("10.2U") # 变性失败,长得不像浮点数
转 complex 类型:
complex(3) # 能转成数值,就能变性成功,输出 (3+0j)
complex(5.2) # 能转成数值,就能变性成功,输出 (5.2+0j)
complex("3+5j") # 长得像复数,输出 (3+5j)
complex("3 + 5j") # 长得像复数,但多了空格,变性失败
转 bool 类型:
bool(0) # 0, -0, "", None 等一切表示为 空 的数据都会被转换为 False
bool(0.00001) # 一切非 空 的数据都会被转换为 True
转 str 类型:
str(1024) # 一切数据都可以被转换为字符串类型,输出字符串 1024
3.5 变量
有了数据之后,该如何存取数据呢?这是一件很重要的事情,是时候该 变量
上场了。
在初等数学里,变量或变元、元是一个用来表示值的符号,该值可以是随意的,也可能是未指定或未定的。在代数运算时,将变量当作明确的数值代入运算中,可以于单次运算时解出多个问题。一个典型的例子为一元二次公式,该公式可以解出每个一元二次方程的值,只需要将方程的系数代入公式中的变量即可。
在小 Python 的世界中,变量
是指一个可以通过名称存取任意字面量的一种标志符号,该表示符号需要遵循一定的规范:
-
标识符可以由字母、数字、下画线(_)组成,其中数字不能打头
-
标识符不能是 Python 关键字,但可以包含关键字(附图)
-
命名规范
- 蛇形命名法:所有单词全小写,单词与单词之间使用 _ 连接,小 Python 推荐的命名方式,如:student_name
- 小驼峰命名法:第一个单词全小写,其余每个单词的首字母大写,如:studentName
- 大驼峰命名法:每一个单词的首字母大写,其余小写,如:StudentName
- 是否缩写:推荐全写
-
申明使用
variable_name = 520 # 将右边的 520 的内容赋值给左边的变量 variable_name
3.6 输入输出
现在你可以很轻松的进行数据的存取操作了,但你得让程序和人交互,就少不了需要用户提供数据,以及向用户展示数据,这就是非常重要的输入(input)和输出(print)操作。
input:使用 input([prompt])
读取一行,将其转换为字符串类型并返回,input
的参数可有可无,如果有参数的话,会在控制台(可以这样理解)输出参数的内容,不换行。通常情况下我们在控制台输入一些数据,然后敲击回车,就完成了本次输入。
name = input("请输入您的大名: ")
print(name)
print:为了向用户显示一些信息,一般在控制台中用 print
进行输出,因为比较简单,所以之前也一直在使用。print
的原型如下:
print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
看起来很复杂,但是这个参数都是有默认参数的,我们可以先简单使用前三个参数,后面的默认即可,这样的话,目前而言,我们的 print
就变成了
print(*objects, sep=' ', end='\n')
第一个参数是我们要在控制台输出的数据,可以是多个,用 ,
逗号隔开,**小 Python **的 print
很强大,可以输出很多种数据类型,只要你觉的可以输出的,print
都可以输出,你觉得不能输出的,试一试也可能输出。例如:
name = input("请输入您的大名:")
print(name) # 输出变量指向的内容
print("xx") # 输出字符串内容
print(520) # 输出数值
sep
用来将多个数据隔开,默认是空格,end
加在输出的末尾,默认是换行符。
print(1,2,3,sep='&&',end='<>\n') #用 && 分隔数据,结尾加上 <> 并换行(\n)
关于输入输出,还有更多有趣强大的功能,后续我们继续探索。
3.7 运算符
有了数据之后,我们应该做点有意思的事了,不能让一个个的数据在那里自顾自的自嗨模式。要将它们拉到一块,这样才热闹。那谁将扮演这样的一个角色呢,运算符,这个用于执行程序代码运算,会针对一个以上数据(准确的描述叫操作数)来进行运算。例如:2+3,其操作数是2和3,而运算符则是“+”。
不同编程语言的运算符略有差别,但大部分相同,最简单的两类是从小学就开始接触的:
算术运算符:
运算符 | 描述 | 实例 | 说明 |
---|---|---|---|
+ | 加 | 20 + 10 | 结果为 30 |
- | 减 | 20 - 10 | 结果为 10 |
* | 乘 | 20 * 10 | 结果为 200 |
/ | 除 | 20 / 8 | 结果为 2.5 |
// | 取整除 | 20 // 8 | 结果为 2 |
% | 取余 | 20 % 8 | 结果为 4 |
** | 幂次方 | 20 ** 3 | 结果为 8000 |
关系运算符:
运算符 | 描述 | 说明 |
---|---|---|
== | 值等于 | 检查两个操作数的值是否相等 |
!= | 值不等于 | 检查两个操作数的值是否不相等 |
<> | 值不等于 | 检查两个操作数的值是否不相等,类似于!= |
> | 大于 | 检查左操作数是否大于右操作数 |
>= | 大于等于 | 检查左操作数是否大于或者等于右操作数 |
< | 小于 | 检查右操作数是否大于左操作数 |
<= | 小于等于 | 检查右操作数是否大于或者等于左操作数 |
另外还有见过的但说法上有变化的运算符,如:
赋值运算符:
运算符 | 描述 | 实例 | 说明 |
---|---|---|---|
= | 赋值 | number = 520 | 表示将右边的结果赋值给左边的变量 |
复合赋值运算符:
运算符 | 描述 | 实例 | 说明 |
---|---|---|---|
+= | 加法赋值 | a += b | 等效于 a = a + b |
-= | 减法赋值 | a -= b | 等效于 a = a - b |
*= | 乘法赋值 | a *= b | 等效于 a = a * b |
/= | 除法赋值 | a /=b | 等效于 a = a / b |
//= | 取整除赋值 | a //= b | 等效于 a = a // b |
%= | 取模赋值 | a %= b | 等效于 a = a % b |
**= | 幂赋值 | a **= b | 等效于 a = a ** b |
逻辑运算符:
运算符 | 描述 | 实例 | 说明 |
---|---|---|---|
and | 与 | exp1 and exp2 | bool(exp1) 的结果为 True 时,返回 exp2 的结果; bool(exp1) 的结果为 False 时,返回 exp1 的结果 |
or | 或 | exp1 or exp2 | bool(exp1) 的结果为 True 时,返回 exp1 的结果; bool(exp1) 的结果为 False 时,返回 exp2 的结果 |
not | 非 | not exp1 | bool(exp1) 的结果为 True 时,返回 False; bool(exp1) 的结果为 False 时,返回 True; |
4. 程序设计基本结构
再次回看程序代码,似乎很傻,如果用户一不小心输入了一个非数值的东西呢?再或者如果用户输入的是50,100,200,1000,...这样的数值呢,那这里写的程序不就歇菜了吗!所以你应该再努力思考一下,该如何优化我们的思维呢?
如果用我们高中数学中的算法流程图来表示的话,大致如下:
这个流程图,各位博客还熟悉吗?有没有勾起的你一丝回忆,有没有勾起你的初恋,😄 ,这里其实就涉及到了流程图的一些基本结构,而这些结构和程序设计中的基本结构可以说是师出一处的。
4.1 顺序结构
在顺序结构中,各个步骤是按先后顺序执行的,这是一种最简单的基本结构。如图,A、B、C是三个连续的步骤,它们是按顺序执行的,即完成上一个框中指定的操作才能再执行下一个动作。在程序中的体现,就是一行一行的往下执行,不需要任何的判断选择,我们截至目前缩写的程序都是属于这种结构的。
4.2 选择结构
选择结构又称分支结构,选择结构用于判断给定的条件,根据判断的结果判断某些条件,根据判断的结果来控制程序的流程。在实际运用中,某一判定结果可以为空操作。
对应到 小 Python 的世界里,选择结构的语法约束可表示为:
# if ... else ...
if expression:
do_something # bool(expression) 为 True 时,执行该处的的代码,必须要缩进对齐,这是强制规范
else:
do_else_something # bool(expression) 为 False 时,执行该处的的代码,也必须要缩进对齐
# if ...
if expression:
do_somthing # bool(expression) 为 True 时,执行该处的的代码,省略了 else 部分
# if ... elif ... else ...
if expression_1:
do_1_something # bool(expression_1) 为 True 时,执行该处的的代码
elif expression_2:
do_2_something # bool(expression_2) 为 True 时,执行该处的的代码
... # 无限多个 elif expression_n 对应的操作
else:
do_else_something # 所有 bool(expression_1,2,...,n) 为 False 时,执行该处的的代码
代码演示:
"""
文件名:mock_login.py
用途:通过模拟登录演示 if 的使用
作者:Mr.潘
"""
# 模拟登录功能
SYSTEM_USER = "pansf"
SYSTEM_PASSWORD = "123456"
user_name = input("登录帐号:")
user_password = input("密码:")
if user_name == SYSTEM_USER and user_password == SYSTEM_PASSWORD:
print("登录成功,可以进入系统主页!")
else:
print("帐号与密码不匹配,请重新尝试!")
4.3 循环结构
循环结构又称为重复结构,就是流程在一定的条件下,反复执行某一操作的流程结构。循环结构下又可以分为当型结构和直到型结构。循环结构可以看成是一个条件判断条件和一个向回转向条件的组合,循环结构的包括三个要素:循环变量、循环体和循环终止条件。但在 小 Python 的世界里,只有当型结构的语法。
对应到 小 Python 的世界里,循环结构的语法约束可表示为:
# while 形式
while expression:
do_something # bool(expression) 为 True 时,执行该处的的代码,必须要缩进对齐,这是强制规范
while expression:
do_something # bool(expression) 为 True 时,执行该处的的代码,必须要缩进对齐
else:
do_else_something # 可省略块,bool(expression) 为 False 时,执行该处的的代码,必须要缩进对齐
# for 形式
for item in items:
do_something # 让 item 从 items(数据集合) 中逐个取值(遍历),然后针对每一次取值都会执行 do_something
for item in items:
do_something
else:
do_else_something # 可省略块,items 被遍历完之后,执行该语句
PS:
items 的角色是一个数据的集合(序列),可以是:
range(start, end, step):生成一个等差数列,如 {1, 2, 3, 4, 5}
start: 数列的第一个值,默认值为 0,可以省略
end: 数列的最后一个值,但该值取不到
step: 数列的差值,默认值为 1,可以省略
字符串:字符集合
代码演示(while):
"""
文件名:mock_login_three_times.py
用途:通过模拟登录演示 while 的用法,允许登录密码错误 3 次
作者:Mr.潘
"""
# 引入一个其它功能,用于模拟生成两个数字的密码
import random
# 模拟登录功能
SYSTEM_USER = "pansf"
SYSTEM_PASSWORD = str(random.randint(10, 20)) # 生成一个 10 到 20 之间的整数,作为登录密码
login_times = 0
while login_times < 3:
login_times += 1 # 记录登录次数
user_name = input("登录帐号:")
user_password = input("密码:")
if user_name == SYSTEM_USER and user_password == SYSTEM_PASSWORD:
print("登录成功,可以进入系统主页!")
else:
print("帐号与密码不匹配,请重新尝试!")
else:
print("登录次数过多,帐号被锁定,请稍候尝试!")
代码演示(for):
"""
文件名:mock_login_three_times.py
用途:通过模拟登录演示 for 的用法,允许登录密码错误 3 次
作者:Mr.潘
"""
# 引入一个其它功能,用于模拟生成两个数字的密码
import random
# 模拟登录功能
SYSTEM_USER = "pansf"
SYSTEM_PASSWORD = str(random.randint(10, 20)) # 生成一个 10 到 20 之间的整数,作为登录密码
# login_times 用于记录登录次数,会依次从 range(3) 中取 0, 1, 2
for login_times in range(3):
user_name = input("登录帐号:")
user_password = input("密码:")
if user_name == SYSTEM_USER and user_password == SYSTEM_PASSWORD:
print("登录成功,可以进入系统主页!")
else:
print("帐号与密码不匹配,请重新尝试!")
else:
print("登录次数过多,帐号被锁定,请稍候尝试!")
4.4 循环插曲
当你尝试运行上面的实例程序后,你可能会皱着你那漂亮的眉头问自己,不对啊,这个程序怎么第一次登录成功了,还要再次登录,哪里出了问题了吧!这就是循环中的插曲了,就如同你日复一日年复一年的上班打卡,打卡下班,突然有一天,你购买了张彩票,而且走了狗屎运,居然中了500万大奖(记得请我吃个饭😋 ),估计你会当机立断的终止你的工作,“想着世界太大,我要出去看看”,当然也存在把 500 万挥霍完之后,再回归工作的情况,这就是插曲。为了实现这种效果,小 Python 提供了 break
和 continue
来完成这个事。
while expression:
do_something_1
break # 遇到 break 后,整个循环就终止了,不会再重复了,也不会运行 else 的代码
do_something_2
while expression:
do_something_1
continue # 遇到 continue 后,跳过后续的操作,继续进入下一轮循环
do_something_2
PS:for 语句类型
这个时候,你可以在脚本 mock_login_three_times.py
中登录成功之后,很自信的添加一个 break
来停止一次次的登录了。
5. 总结
关于小Python 之核心语法暂且就讲到这里,深度探索,待后续博文发力,现在你可以再次回到博文开头,完成尚需解决的两个问题了,如有问题可询问我。