万事俱备了,马上就可以磨刀霍霍向 Python 了。那如何开始呢,再回到开篇介绍的“编程本色”中,将几个问题的解决思路拿到此处,开启编程之旅。

1. 问题回顾

1.1 数学问题

  • 求和(n 为偶数,n >= 1)

49.png

  1. 拿出一个本子或者一张纸,一支笔,准备开干
  2. 写上问题描述信息,自己的姓名,时间等信息
  3. 询问提问者 n 的值为多少(如:n = 10)
  4. 计算 1 - 1/2 = 1/2
  5. 计算 1/2 + 1/3 = 5/6
  6. 依次类型,追个向下计算
  7. 计算出最终的结果,并将最终结果告诉提问者

1.2 生活问题

  • 根据江苏省最新个税法,根据员工薪资,计算个人所得税及税后收入

2. 进入编程世界

2.1 思维步骤

  1. 创建一个目录(包),进入目录中创建一个以 .py 结尾的文本文件(模块),打开文件准备开干(写代码)
  2. 写上一些信息,用于说明该文件的用途、作者、时间的信息(注释)
  3. 提示用户输入 n 数值(input),并将这个值暂存下来,标识为 n (变量),以备后续使用
  4. 第一次计算,将 1 - 1/2 的结果存下来,标识为 s1 (变量),以被下一步使用
  5. 第二次计算,将上一步的结果 s1 + 1/3 的结果存下来,标识为 s2 (变量),以被下一步使用
  6. 重复上面的步骤,直到第 n 次计算,将上一步的结果 sn-1 + 1/n 的结果存下来,标识为 sn
  7. 输出最终的计算结果 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 的世界中,变量是指一个可以通过名称存取任意字面量的一种标志符号,该表示符号需要遵循一定的规范:

  1. 标识符可以由字母、数字、下画线(_)组成,其中数字不能打头

  2. 标识符不能是 Python 关键字,但可以包含关键字(附图)

  3. 命名规范

    1. 蛇形命名法:所有单词全小写,单词与单词之间使用 _ 连接,小 Python 推荐的命名方式,如:student_name
    2. 小驼峰命名法:第一个单词全小写,其余每个单词的首字母大写,如:studentName
    3. 大驼峰命名法:每一个单词的首字母大写,其余小写,如:StudentName
    4. 是否缩写:推荐全写
  4. 申明使用

    variable_name = 520	# 将右边的 520 的内容赋值给左边的变量 variable_name
    

51.jpg

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

逻辑运算符

运算符描述实例说明
andexp1 and exp2bool(exp1) 的结果为 True 时,返回 exp2 的结果;
bool(exp1) 的结果为 False 时,返回 exp1 的结果
orexp1 or exp2bool(exp1) 的结果为 True 时,返回 exp1 的结果;
bool(exp1) 的结果为 False 时,返回 exp2 的结果
notnot exp1bool(exp1) 的结果为 True 时,返回 False;
bool(exp1) 的结果为 False 时,返回 True;

4. 程序设计基本结构

再次回看程序代码,似乎很傻,如果用户一不小心输入了一个非数值的东西呢?再或者如果用户输入的是50,100,200,1000,...这样的数值呢,那这里写的程序不就歇菜了吗!所以你应该再努力思考一下,该如何优化我们的思维呢?

如果用我们高中数学中的算法流程图来表示的话,大致如下:

52.png

这个流程图,各位博客还熟悉吗?有没有勾起的你一丝回忆,有没有勾起你的初恋,😄 ,这里其实就涉及到了流程图的一些基本结构,而这些结构和程序设计中的基本结构可以说是师出一处的。

4.1 顺序结构

在顺序结构中,各个步骤是按先后顺序执行的,这是一种最简单的基本结构。如图,A、B、C是三个连续的步骤,它们是按顺序执行的,即完成上一个框中指定的操作才能再执行下一个动作。在程序中的体现,就是一行一行的往下执行,不需要任何的判断选择,我们截至目前缩写的程序都是属于这种结构的。

53.png

4.2 选择结构

选择结构又称分支结构,选择结构用于判断给定的条件,根据判断的结果判断某些条件,根据判断的结果来控制程序的流程。在实际运用中,某一判定结果可以为空操作。

54.png

对应到 小 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 的世界里,只有当型结构的语法。

55.png

对应到 小 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 提供了 breakcontinue 来完成这个事。

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 之核心语法暂且就讲到这里,深度探索,待后续博文发力,现在你可以再次回到博文开头,完成尚需解决的两个问题了,如有问题可询问我。