程序基本程结构
- 流程图
-
三种程序设计基本结构
- 顺序结构
- 选择结构
- 循环结构
简单分之
if语句格式
语句格式如下
if <condition>:
<body>
其中<condition>是条件表达式,<body>是一个或多个语个或多个语句序列。
先判断<condition>条件:
true,则执行<body>,再转向下一条语句;
false,则直接跳过<body>,转向下一条语句;
简单条件构造
简单条件基本形式
<expr> <relop> <expr>
<relop>是关系操作符<, <=, ==, >=, >, !=
使用“=”表示赋值语句,使用“==”表示等于
除数字外,字符或字符串也可以按照字典顺序用于条
比较
<condition>是布尔表达式,为bool类型,布尔值
真和假以字符True和False表示
二分之决策
二分支语法结构如下:
if <condition>:
<statements>
else:
<statements>
Python解释器首先评估<condition>
如果<condition>是真的,if下面的语句被执行
如果<condition>是假的,else下面的语句被执行。
多分之决策
把一个复合语句放到另一个语句的结构之中称
为嵌套。下面是使用嵌套实现了三分支决策的
多分支决策是解决复杂问题的重要手段之一
一个三分支决策可以由两个二分支结构嵌套实现
使用if-else描述多分支决策时,实现更多分支需要更多嵌套,影响程序的易读性
Python使用if-elif-else描述多分支决策,简化分支结构的嵌套问题
使用if-elif-else描述多分支决策:
if <conditionl>:
<casel1 statements>
elif <condition2>:
<case2 statements>
elif <condition3>:
<case3 statements>
......
else:
<sefault statements>
Python轮流评估每个条件,来寻找条件为True的分支,并
执行该分支下的语句;如果没有任何条件成立,else下面的
语句被进行,else子句是可选的。
异常处理机制
异常处理机制的引入
如果处理错误或特殊情况的分支语句过多,那么处理正常
情况的主程序就会变得不清晰易读、
以前面讲述的二次方程求解为例
discRt = otherSqrt(b*b-4*a*c)
if discRt < 0:
print("No real roots.")
else:
...
引入异常处理机制来解决程序运行时的错误,而不是显式
检查算法的每一步是否成功。
异常处理语句
Python使用try…except…来进行异常处理,基本
格式如下:
try:
<body>
except <ErrorType1>:
<handler1>
except <ErrorType2>:
<handler2>
except:
<handler0>
当Python解释器遇到一个try语句,它会尝试执行
try语句体<body>内的语句
如果没有错误,控制转到try-except后面的语句
如果发生错误,Python解释器会寻找一个符合该错误
的异常语句,然后执行处理代码
TryException.py
def main():
try:
number1,number2 = eval(input("Enter teo numbers,separated by a comma")
result = number1 / number2
except ZeroDivisionError:
print("Division by zero!")
except SyntaxError:
print("A comma may be missing in the input")
except:
print("something wrong in the input")
else:
print("No exceptions,the result is ",result)
finally:
print("executing the final clause")
main()
Try…except可以捕捉任何类型的错误
对于二次方程,还会有其他可能的错误,如:输入非数
值类型 (NameError),输入无效的表达式(SyntaxError)
等。此时可以用一个try语句配多个except来实现。
基本循环结构
for 循环
Python可以使用for语句循环遍历整个序列的值
for <var> in <sequence>:
<body>
在for循环中,循环变量var遍历了队列中的每一个值,循
环的语句体为每个值执行一次。
def main():
words = ["sun","sunflower","want"]
for i in words:
print(i,":",len(i))
main()
注意,for循环在执行过程中,直接在序列上进行
遍历,而非在内存中生成一个新的序列拷贝进行
def main():
words = ["sun","sunflower","want"]
for i in words[:]:
if len(i) > 5:
words.insert(0,i)
print(i,":",len(i))
print(words)
main()
for循环-求平均数
平均数计算程序的IPO如下:
输入:待输入数字个数,数字
处理:平均数算法
输出:平均数
通用设计方案:
输入数字的个数n
将sum初始化为0
循环n次:
输入数字x
将x加入sum中
将sum/n作为平均数输出出来
for循环-代码
def main():
n = eval(input("How many numbers?:"))
sum = 0.0
for i in range(n):
x = eval(input("Enter a number:"))
sum = sum + x
print("\nThe average is : ",sum/n)
main()
for循环-执行
以下是程序的执行结果
How many numbers?:3
Enter a number:2
Enter a number:4
Enter a number:3
The average is : 3.0
for循环-缺点
程序开始时必须提供输入数字总数
大规模数字求平均值需要用户先数清楚个数
for循环是需要提供固定循环次数的循环方式
Python提供了另一种循环模式即无限循环,不需要提前
知道循环次数,即我们提到的当型循环也叫条件循环
无限循环
语法:while语句
while <condition>:
<body>
while语句中<condition>是布尔表达式
<body>循环体是一条或多条语句
当条件<condition>为真时,循环体重复执行
当条件<condition>为假时,循环终止
在while循环中,条件总是在循环顶部被判断,即在循环
体执行之前,这种结构又被称为前测循环
无限循环
下面是使用while循环完成从0到10的
求和打印平均值的例子:
如果循环体忘记累加i,条件判断一直
为真,循环体将一直执行,这就是所
谓的死循环程序
这时通常使用<Ctrl>-c来终止一个程
序
for/while 中的else, break用法
Break 语句- 跳出最内层for/while 循环
for/while 中的continue用法
continue语句, 其作用为结束本次循环。即跳出循环体中下
面尚未执行的语句,对于while循环,继续求解循环条件。而
对于for循环程序流程接着遍历循环列表
continue语句和break语句的区别是:
continue语句只结束本次循环,而不终止整个循环的执行。而break语句则是结束整个循环过程,不再判断执行循环的条件是否成立:
for/while 中的else用法
Break 语句- 跳出最内层for/while 循环
<for… else: …> <while… else: …>语句与循环的搭配使
用,else:后的表达式在for循环列表遍历完毕后或while 条
件语句不满足的情况下执行,例如:
#for/while 中的else 用法
for n in range(2,10):
for x in range(2, n):
if n % x == 0:
print(n, 'equals', x, "*", n//x)
break
else:
#loop fell through eithout finding a factor
print(n, 'is a prime number')
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3
交互式循环
交互式循环是无限循环的一种
允许用户通过交互的方式重复程序的特定部分
让我们以交互循环的视觉重新审视求平均数程序
如下:
初始化sum为0
初始化count为0
初始化moredata为“yes”
当moredata值为“yes”时
输入数字x
将x 加入sum
count值加1
询问用户是否还有moredata需要处理
输出sum/count
交互式循环代码
# average2.py
def main():
sum = 0.0
count = 0
moredata = "yes"
while moredata[0] == 'y':
x = eval(input("Enter a nuber >>")
sum = sum + x
count = count + 1
moredata = input("Do you have more,numbers (yes or no)?")
print("\nThe average of the numbers is ",sum/count)
main()
# average3.py
def main():
sum = 0.0
count = 0
x = eval(input("Enter a number (negative to quit"))
while x >=0:
sum = sum + x
count = count + 1
x = eval(input("Enter a number (negative to quit) >>"))
print("\n The average of the nubers is", sum/count)
main()
交互式循环执行:
Enter a number >>30
Do you have more (yes or no)?y
Enter a number >>20
Do you have more (yes or no)?y
Enter a number >>30
Do you have more (yes or no)?y
Enter a number >>2
Do you have more (yes or no)?n
The avarage of the number is 20.5
哨兵循环
执行循环直到遇到特定的值,循环语句才终止执行的循环结构设计方法
哨兵循环是求平均数的更好方案,思路如下:
设定一个哨兵值作为循环终止的标志
任何值都可以做哨兵,但要与实际数据有所区别伪代码如下:
接收第一个数据
while这个数据不是哨兵
程序执行相关语句
接收下一个数据项
在求考试分数平均数的程序中,可以设定负数为哨兵
代码如下:
# average3.py
def main():
sum = 0.0
count = 0
x eval(input("Enter a number (negative to quit) >>")
while x >=0:
sum = sum + x
count = count + 1
x = eval(input("Enter a number (negative to quit) >>"))
print("\n The average of the numbers is ", sum/count)
main()
执行结果:
Enter a number (negative to quit) >>1
Enter a number (negative to quit) >>2
Enter a number (negative to quit) >>3
Enter a number (negative to quit) >>4
Enter a number (negative to quit) >>5
Enter a number (negative to quit) >>6
Enter a number (negative to quit) >>7
Enter a number (negative to quit) >>-1
The average of the numbers is 4.0
没有那么yes/no的干扰,执行结果更加清晰
但不能包含负数的平均数计算,为了更加通用化需要引入字符串
哨兵循环版本2
利用非数字字符串表示输入结束
所有其他字符串将被转换成数字作为数据处理
空字符串以 “ ”(引号中间没有空格)代表,可以真作为哨兵,用户输入回车Python 就返回空字符串
伪代码如下:
初始化sum为0
厨师还count为0
接受输入的字符串数据,xStr
while xStr非空
将xStr转换为数字x
将x加入sum
count值加1
接受下个字符串数据,xStr
输出sum/count
def main():
sum = 0.0
count = 0
xStr = input('Enter a number (<Ente> to quit>>')
while xStr !="":
x = eval(xStr)
sum = sum + x
xStr = input("Enter a number (<Enter> to quit)>>")
print("\n The average of the numbers is", sum / count)
执行如下:
Enter a number (<Enter> to quit) >> 2
Enter a number (<Enter> to quit) >>4
Enter a number (<Enter> to quit) >>6
Enter a number (<Enter> to quit) >>78
Enter a number (<Enter> to quit) >>-45
Enter a number (<Enter> to quit) >>2
Enter a number (<Enter> to quit) >>0
Enter a number (<Enter> to quit) >>
The average of the number is 6.714285714285714
文件循环
面向文件的方法是数据处理的典型应用
之前求平均数的数字都是用户输入的,如果几百个数求平均,输入困难期容易出错
可以事先将数据录入到文件中,然否将这个文件作为程序输入,避免人工输入的麻烦, 便于编辑修改
文件循环代码
# average5.py
def main():
fileName = input("What file are the numbers in")
infile = open(fileName, 'r')
sum = 0
count = 0
for line in infile:
sum += eval(line)
count +=1
print("\nThe average of the number is", sum/count)
main()
遍历文件
在这段代码中,循环变量line遍历文件的每一行,将每行都转成数字加到sum中。
通过Python的readerline()来读取,reafline()将文件的每一行读取到字符串中。
在文件尾部,resdderline()返回的一个空字符串可以作为哨兵值。
Python中采用readerline()方法的end_of_file循环模式:
line = infile.readerline()
while line != "":
#处理每一行
line = infile.readerline()
文件循环代码while
将end-of-file 哨兵循环应用到平均数问题的代码如下:
def main():
fileName = input("What file are the numbers in? ")
infile = open(fileName,"r")
sum = 0
count = 0
line = infile.readline()
while line !="":
sum = sum + eval(line)
count = count+1
line = infile.readerline()
print("\nThe average of number is", sum / count)
main()
嵌套循环
决策和循环互相嵌套可以实现复杂的算法
之前示例中文件每行值存一个数字,这一次数字以逗号分割出现在文件的同一行上
下面是处理一行的代码片段:
for xStr in file.split(","):
sum = sum + eval(xStr)
count = count+1
嵌套循环代码
# average7.py
def main():
fileName = input("What file are the numbers in?")
infile = open(fileName, "r")
sum = 0.0
count = 0
line = infile.readerline()
while line !="":
#外循环:while语句对没行循环一次 #为line中的值更新其count和sum
for xStr in line.split(","):
#内循环:for语句对一行中的每个数字进行循环
sum +=eval(xStr)
count +=1
line = infile.readerline()
print("\nThe average of the numbers is ", sum/count)
main()
死循环
死循环的使用
四循环并非一无是处,c语言中死循环while true或while 1 是单片机编程的普通用法,死循环一直运行等待中断程序发生,然后去处理中断程序
在Python中我们也可以利用死循环完成特定功能
while True:
try:
x = int(input("Please enter a number:"))
break
except ValueError:
print("Oops, that was no valid number.Try again...")
代码执行如下:
Plece enter a number :k
Oops, that was no valid number. Try again...
Plece enter a number :k
Oops, that was no valid number. Try again...
Plece enter a number :9
后侧循环
假设程序需要用户输入一个非负数
如果输入错误,重新提示用户输入直到得到一个有效值
为代码如下:
重复执行以下语句
接受外部输入数据
直到外部输入为负值为止
循环不断接收输入,直到接受到合法的值为止
条件判断在循环体后面,称之为后测循环
后测循环至少执行一次循环体
后侧循环实现
Python没有后测循环语句,但可以通过while循环间接实现
思想是设计一个循环条件,直接进入循环体,循环至少执行一次,相当于后测循环
nubmber = -1
while number < 0:
number = eval(input("Enter a positive number: "))
代码执行如下:
Enter a positive number: -1
Enter a positive number: -2
Enter a positive number: 3
break语句也可以用来实现后侧循环
while True:
number = eval(input("Enter a positive number:" ))
if x >= 0:
break
#如果数字有效则跳出循环
while语句体永远执行,if条件决定循环退出
另外:if语句体只包含一个语句时。break可以跟if在同一行
代码执行如下:
Enter a positive number:-1
Enter a positive number:0
后侧循环代码1
在前面的while版本的后侧循环代码中添加一个if语句,使得在有效输入时不显示警告
修改代码如下:
number = -1
while number < 0:
number = eval(input("Enter a poditive number: "))
if number < 0:
print("The number you entered was not positive")
代码执行如下:
Enter a positive number:-1
The number you entered was not positive
Enter a positive number:-2
The number you entered was not positive
Enter a positive number:0
后侧循环代码2
限定合法性检验只判断一次,需为if添加匹配的else语句来实现
修改的代码如下:
while True:
number = eval(input("Enter a positive number: "))
if x >= 0:
break #如果数字有效则跳出循环
else:
print("The number you entered was not positive")
代码执行如下:
Enter a positive number:-1
The number you entered was not positive
Enter a positive number:-5
The number you entered was not positive
Enter a positive number:9
半路循环
运用break中途退出循环, 循环出口在循环体中部,被称为半路循环
while True:
number = eval(input("Enter a positive number:"))
if x >=0: break #跳出循环
print("The number you entered was not positive")
半路循环——哨兵
半路循环退出实现哨兵循环的一般模式
while True:
Get next data item
if the item is the sentinrl: break
process thw item
在程序中是否使用break语句,跟个人编程风格有关。
应避免在一个循环体内使用过多的break语句。因为当循环有多个出口的时候,程序逻辑就显得不过清晰了。
布尔表达式
条件语句和循环语句都使用布尔表达式作为条件
布尔值为真或假,以False和True表示
前面经常使用布尔表达式比较两个值,如:while x>= 0
布尔操作符的引入
简单条件在复杂决策情况下存在缺陷
例如,确定两个点是否是在同一个位置,即是否有相同的x坐标和y坐标,下面是处理的代码片段:
if p1.getX() == p2.getX():
if p1.getY() == p2.getY():
# 两点相同
else:
# 两点不同
else:
#两点不同
过于复杂,Python提供了更简单的布尔操作符来构建表达式
布尔操作符
布尔操作符: and ,or 和 not
布尔操作符and和or用于组合两个布尔表达式,并产生一个布尔结果
<expr> and <expr>
<expr> or <expr>
not运算符是一个一元运算符,用来计算一个布尔表达式的反
not <expr>
使用布尔运算符,可以建立任意复杂的布尔表达式
例如:a or not b and c
Python中布尔操作符的优先级,从高分到低分依次是not,and最低是or.所以上面的表达式等于如下这个带有括号的版本:(a or ((not b) and c))
使用and操作符改进之前比较两个点相同的例子
if p1.getX() == p2.getX() and p2.getY() == p1.getY():
#两点相同
else:
#两点不同
简单,清晰
壁球比赛积分例子
假设scoreA和scoreB代表两个选手分数
规则: 只要一个选手达到了15分,本场比赛就结束。
即如下布尔表达式为真时比赛结束:
scoreA == 15 or scoreB == 15
可以构造循环条件,对游戏结束条件取反:
while not(scoreA == 15 or scoreB == 15):
# 比赛继续
a和b 代表两个壁球选手的分数
规则1: 只要一个选手达到了15分,本场比赛就结束,如果一方打了七分而另一方一分未得时,比赛也会结束
(a>=15 or b >= 15) and abs(a-b)>=2
规则2:需要一个团队赢得至少两分才算赢,即其中一个队已经达到了15分,且分数差异至少为2时比赛结束
(排球) (a >= 15 and a-b>=2) or (b>=15 and b-a >=2)
等价于 (a>=15 or b<=15) and abs(a-b)>=2
abs函数返回表达式的绝对值
布尔代数
布尔表达式遵循特定的代数定律,这些规律被称为布尔逻辑或布尔代数
布尔代数规则
Algebra | Boolearn algebra |
---|---|
a*0 = 0 | a and false == false |
a*1 = a | a and true == a |
a+0 = a | a or false == a |
当0和1对应false和true时
and与乘法相似
or与加法相似
条件输入:
def main():
a ,b= eval(input("Pleace enter a and b number:"))
while True:
if (a >=15 or b>=15) and abs(a-b)>=2:
print("The game over" ,abs(a-b))
break
else:
print("Pleace enter two number again")
a ,b= eval(input("Pleace enter a and b number:"))
main()
代码执行如下:
Pleace enter a and b number:12,13
Pleace enter two number again
Pleace enter a and b number:12,45
The game over 33
任何值和true进行 “or” 操作都是真
a or true == true
and 和 偶然操作符都符合分配率:
a or (b and c) == (a or b) and (a or c)
a and (b or c) == (a and b) or (a and c)
not 操作符具有负负抵消的特征:
not(not a) == a
布尔代数符合德摩根定律,not放进表达式后,and和运算符之间发生都得变化:
not (a or b) == (not a) and (not b)
not(a and b) == (not a) or (not b)
布尔代数的应用
while not (scoreA == 15 or scoreB == 15):
#比赛继续
通过使用布尔代数, 可以转换上面这个表达式。应用德摩根定律,其等同于下面这个表达式:
(not scoreA ==15) and (not scoreB ==15)
注意,当使用not的分分配率时,or和and的转变。
while scoreA != 15 and scpreB !=15:
# 比赛继续
布尔表达式作为决策
在Python中,布尔表达式是很灵活的。
回顾交付式循环,只要用户相应一个“Y”,程序就继续。
while response[0] == "y" or response[0] == "Y"
初学者注意不要将上述表达式写成以下的形式
while response[0]== "y" or "Y":
其实这是一个无限循环。请思考为什么哲理的条件表达式值总为真?
Python的条件运算符(即==)总是在与一个bool类型的值进行比较!
布尔True和False来代表布尔值的真和假
对于数字(整型和浮点型)的零值被认为是false
任何非零值都是True
bool 类型仅仅是一个特殊的整数,可以通过计算表达式 True + True的值来测试一下
对于系列类型来说,一个空系列解释为假,任何一个非空系列解释为真
bool(0)
False
bool(1)
True
bool(32)
True
bool("helllo")
True
bool("")
False
bool([1,2,3])
True
bool([])
False
布尔表达式思考
Python的布尔灵活也扩展到了布尔运算符。下表总结了这些运算符都得特征
operator | operational definition |
---|---|
x and y | If x is false, return x.Otherwise, return y |
x or y | If x is true, return x, Otherwise, return y |
not x | If x is false , return True,Otherwise, return False |
Pytnon的布尔运算符是短路运算符。
Python从左到右扫描表达式一旦知道结果,就立即返回True或False值
while response[0] == "y" or response[0]=="Y":
while response[0] == "y" or "Y"
思考上面两条代表码有何区别
第二个表达式“Y”, 它是一个非空的字符串,所以Python会永远把它解释为真
### 布尔表达式简洁表示
如果用户仅仅简单敲下回车键,可以使用方括号中的值作为默认值
ans = input("What flavor do you want [vanilla]:")
if ans !="":
flavor = ans
else:
flavor = "vanilla"
可以简化如下:
ans = input("What flavor do you want [vanilla]:")
if ans:
flavor = ans
else:
flavor = "vanilla"
更简单的表达形式
ans = input("What flavor do you want [vanilla]:")
flavor= ans or "vanilla"
or 操作符的定义保证它等价于if-else结构,
进一步简化:
flavor = input("What flavor do you want [vanilla]:") or "vanilla"