【4-程序的控制结构】嵩天《Python语言程序设计》

目录

前课复习

​程序的控制结构

一、程序的分支结构 

1、单分支结构

2、二分支结构

3、多分支结构

4、条件判断及组合

5、程序的异常处理

总结

二、实例5:身体质量指数BMI 

1、问题分析

2、思路1:分别计算并给出国际和国内BMI分类

3、思路2:混合计算并给出国际和国内BMI分类

4、举一反三

三、程序的循环结构 

1、遍历循环:保留字 for in 构成

2、无限循环(条件循环):保留字 while

3、循环控制保留字:break 和 continue

4、循环的高级用法(通过else给奖励)

总结

四、模块3:random库的使用

​1、基本随机数函数

2、扩展随机数函数

五、实例6:圆周率的计算 

1、公式计算

2、蒙特卡罗方法计算 

3、举一反三


前课复习

if - elif -else 分支结构
for i in range 循环结构

程序的控制结构

  1. 顺序结构:程序按照线性顺序逐渐执行的结构
  2. 分支结构:程序根据条件有选择的向程序运行方向执行的结构
  3. 循环结构:程序根据一定条件向程序运行之后,也就是程序曾经执行过方向返回执行的结构

一、程序的分支结构 

1、单分支结构

分支结构是根据判断条件结果而选择不同向前路径的运行方式

guess = eval(input())
if guess == 99:
    print("猜对了")

判断条件可以直接使用真假来表示,只要见到 if True,后面的语句就会被执行

if True:
    print("条件正确")

2、二分支结构

根据条件判断的不同而选择不同执行路径的一种结构

guess = eval(input())
if guess == 99:
    print("猜对了")
else:
    print("猜错了")
if True:
    print("语句块1")
else:
    print("语句块2")   # 事实上这部分永远不会被执行

二分支结构除了简单的 if else 之外,还需知道一种紧凑形式

  • 仅适用于表达简单逻辑的二分支结构的一种紧凑方式
  • 优点:简洁
  • if else 对应的输出不是语句,而是表达式。所谓的表达式是语句的一部分,简单理解为:语句为带赋值形式的、有等号构成的语句,而 if else 的紧凑形式不支持这种带等号的赋值形式,它只支持表达式形式,也就是语句中的一部分

当条件成立了返回表达式1的信息,当条件不成立else后的表达式2被执行 

guess = eval(input())
print("猜{}了".format("对" if guess == 99 else "错"))

上例中的 “对” “错” 都是表达式,而不是带等号的赋值形式

3、多分支结构

根据多个条件来选择不同语句块运行的一种分支结构

  • 注意多条件之间的包含关系 
  • 注意变量取值范围的覆盖

例:对不同分数分级的问题

score = eval(input())
if score >= 90:
    grade = "A"
elif score >= 80:
    grade = "B"
elif score >= 70:
    grade = "C"
elif score >= 60:
    grade = "D"
print("输入成绩属于级别{}".format(grade))

4、条件判断及组合

分支语句中需要大量的条件判断,Python提供了一些操作符来对条件进行判断,并产生真或假的结果

除了操作符之外,Python 也提供了三个用来对条件进行组合的保留字

  • x and y:条件x成立,条件y也成立,那么经过and操作符获得的结果才是真值
  • x or y:两个条件x y进行逻辑或,只要有x和y中的一个条件成立,那么组合后的结果就是成立的 
  • not x:对条件x进行逻辑取非
guess = eval(input())
if guess>99 or guess<99:
    print("猜错了")
else:
    print("猜对了")
if not True:   # 表达假的逻辑,即False
    print("语句块2")   # 永远不会被执行
else:
    print("语句块1")   # 只会执行语句块1

5、程序的异常处理

  • 异常处理有两种非常基本的使用方法,使用保留字 try 和 except
  • 进一步也可以指定异常处理的异常类型,在except后面直接增加异常的名字(Python中预定义的)
  • 标注异常类型后,仅响应该类型异常。异常类型名字是Python内部定义的,等同于变量,不需要对它增加字符串表示

例子:

try:
    num = eval(input("请输入一个整数:"))
    print(num**2)
except:
    print("输入不是整数")
try:
    num = eval(input("请输入一个整数:"))
    print(num**2)
except NameError:
    print("输入不是整数")

异常处理的高级使用方法 

  • 首先执行语句块1的一部分代码,若它不发生异常,奖励性地让它执行语句块3,;若发生异常,让它执行语句块2;无论发不发生异常,最后都要执行语句块4 
  • 这种方式可以增加更多的异常处理相关逻辑,使得异常处理变得非常鲁棒

总结


二、实例5:身体质量指数BMI 

1、问题分析

 

2、思路1:分别计算并给出国际和国内BMI分类

# CalBMIv1.py(国际)
# 用户输入是多元素,建议采用逗号隔开
height,weight = eval(input("请输入身高(米)和体重(公斤)[逗号隔开]:"))
bmi = weight /pow(height,2)
print("BMI数值为:{:.2f}".format(bmi))
who = ""
if bmi < 18.5:
    who = "偏瘦"
elif 18.5 <= bmi < 25:
    who = "正常"
elif 25 <= bmi <30:
    who = "偏胖"
else:
    who = "肥胖"
print("BMI指标为:国际'{0}'".format(who))
# CalBMIv2.py(国内)
# 用户输入是多元素,建议采用逗号隔开
height,weight = eval(input("请输入身高(米)和体重(公斤)[逗号隔开]:"))
bmi = weight /pow(height,2)
print("BMI数值为:{:.2f}".format(bmi))
nat = ""
if bmi < 18.5:
    nat = "偏瘦"
elif 18.5 <= bmi < 24:
    nat = "正常"
elif 24 <= bmi < 28:
    nat = "偏胖"
else:
    nat = "肥胖"
print("BMI指标为:国内'{0}'".format(nat))

3、思路2:混合计算并给出国际和国内BMI分类

# CalBMIv3.py(混合计算)
height,weight = eval(input("请输入身高(米)和体重(公斤)[逗号隔开]:"))
bmi = weight /pow(height,2)
print("BMI数值为:{:.2f}".format(bmi))
who,nat = "",""
if bmi < 18.5:
    who ,nat = "偏瘦" ,"偏瘦"
elif 18.5 <= bmi < 24:
    who ,nat = "正常","正常"
elif 24 <= bmi < 25:
    who ,nat = "正常","偏胖"
elif 25 <= bmi < 28:
    who,nat = "正常","偏胖"
elif 28 <= bmi < 30:
    who,nat = "偏胖","肥胖"
else:
    who,nat = "肥胖","肥胖"
print("BMI指标为:国际'{0}',国内'{1}'".format(who,nat))

4、举一反三


三、程序的循环结构 

1、遍历循环:保留字 for in 构成

遍历某一个结构形成的循环运行方式

  • 可以从遍历结构中逐一提取元素,放到循环变量
  • 使用的遍历结构,是一种能够包含多个元素的结构。所谓遍历结构,不是一种特殊的类型,它包含很多种类型
  • 每次循环时,能够从遍历结构中提取其中的一个元素,放到前面的循环变量里,去执行下面的语句块,执行后再从遍历结构中提取下一个元素。当遍历结构中的所有元素都放入循环变量,并且都已经循环执行之后,程序退出

遍历循环的应用

  1. 计数循环(N次)  range函数
    遍历下面的语句块,执行N次语句块的内容
    range(N) 函数产生一个数字序列,这个序列包含N个元素,每个元素都是一个整数(从 0 到N-1),例:

    也可以在中间的语句块中不使用变量i
  2. 计数循环(特定次)   range函数
    range是函数,M、N、K是函数的参数
    range(M,N,K) 会产生一个数字序列,从M开始,不到N,到N之前的整数,以K为步长,例:
  3. 字符串遍历循环

    s是一个字符串,c是字符串中的每个字符,能够从字符串中按顺序取出每一个字符放到c中。而针对每一次取出的字符,执行一次语句块,进而产生循环。例:
    在打印的每个字符后面增加一个逗号
    c可以为任何可用的、与保留字不同的变量名称
  4. 列表遍历循环
    ls 为一个列表,遍历列表,将其中的每一个元素拿出来放到 item 变量中,同时执行一次当前的语句块产生循环
  5. 文件遍历循环
    遍历文件的每一行

    fi 为一个文件标识符(对一个外部文件,通过Python函数将文件打开,如果该文件是以字符形式打开,就会表示为一个文件的标识的名字。相当于用一个变量来标识系统中的一个文件,这个变量就叫文件标识符)
  6. 元组遍历循环
  7. 字典遍历循环
  8. ....

所有 for in 这样可遍历的结构,只要后边的变量或者数据类型是一个由多个元素构成的数据类型,都可以使用 for in 的方式遍历其中的每一个元素,并且根据元素的个数形成相应的循环

2、无限循环(条件循环):保留字 while

由条件控制的循环运行方式

  • 不再是遍历某一个结构,而是根据这个条件来进行循环 
  • 反复执行语句块,直到条件不满足时结束

3、循环控制保留字:break 和 continue

continue 例子

遍历一个字符串,如果这个字符串中出现了T,就不打印T,否则打印其他的所有字符出来

在当次循环体执行时,如果遇到了continue保留字,当次循环就结束,去做下一次循环

break 例子

遇到break,整个循环结束。若程序有两层或更多层循环,break该怎么办呢?

# 最开始给出一个字符串,每次循环将字符串的最后一个字符去掉,打印出字符串

s = "PYTHON"

# 双层循环
while s != "":    # 若字符串s不是空字符串
    for c in s:   # 将字符串中的每一个字符拿出来
        print(c,end="")
    s = s[:-1]  # 去掉s的最后一个字符

一个break保留字仅跳出当前的最内层循环,若有多层循环嵌套,它只跳出内层,外层循环仍然有效 

# 取出一个字符串,只要遇到T就停止遍历,将字符串的最后一位去掉,再去遍历,遇到T还停止遍历

s = "PYTHON"

# 双层循环
while s != "":    # 若字符串s不是空字符串
    for c in s:   # 将字符串中的每一个字符拿出来
        if c== "T":
            break  # 仅跳出当前最内层循环(一个break只能跳出一层循环)
        print(c,end="")
    s = s[:-1]  # 去掉s的最后一个字符

4、循环的高级用法(通过else给奖励)

通过else的扩展,能够知道一段循环中是否被break结束 

# 无break语句,循环结束后,将打印出正常退出的这段代码

for c in "PYTHON":
    if c == "T":
        continue
    print(c,end="")
else:
    print("正常退出")

 

# 有break,else部分的正常退出语句就不会被执行

for c in "PYTHON":
    if c == "T":
        break
    print(c,end="")
else:
    print("正常退出")

总结


四、模块3:random库的使用

1、基本随机数函数

  • Python中的随机数采用随机数种子来产生
  • 计算机产生随机数,是需要一个随机数种子的,给定一个种子(比如10),再采用梅森旋转算法,就能够根据种子产生一系列的数据,那么这个随机序列是根据种子来唯一确定的,随机序列中的每一个数就是随机数
  • 只要种子相同,产生的随机序列,无论是每一个数,还是数之间的关系,都是确定的
  • 随机数种子确定了随机序列的产生

  • seed:在使用随机数时,可以不调用seed函数,可以直接调用random.random()来产生随机数,不需要使用seed函数。若不使用或不调用seed函数时,将会使用当前操作系统的默认的系统时间作为种子 
  • random:生成一个从0开始,到1.0之间的随机小数,这个随机小数的产生与种子有关(若用种子10,产生的第一个小数一定是0.57)

 

也可以不给种子, 直接调用 random 也可以产生随机数,此时默认的种子是当前调用第一次random函数所对应的系统时间

为什么要给种子?

  • 若编程中给出了随机种子,那么下一次程序再次运行,只要种子相同,那么产生的随机数也是相同的,对于使用随机数的程序可以复现或再现程序运行的过程,如:
  • 若不使用随机数种子,那么它使用的是当前系统时间,而那个时间是精确到微秒的,很难再现,后面产生的程序运行的结果就是完全随机,不可再现;
  • 综上,需要再现随机过程就设定种子

2、扩展随机数函数

在random库中,最基本的是seed和random函数,除此之外,random库提供了常用的六个扩展随机数函数


五、实例6:圆周率的计算 

1、公式计算

累加求和,累加的变量k从0到无穷大,使用for循环来实现这种累加

代码:

# CalPiV1.py(通过公式计算圆周率的值)

pi = 0
N = 100  # 假设无穷大是N(100)
for k in range(N):
    
    '''若写一段代码特别长,在一行中无法表达,
可以在这段代码中增加\,使代码进行换行,换行后还可以再使用\再进行换行,
且换行之后的代码,它的功能与写在一行是一致的'''

    pi += 1/pow(16,k)*( \
        4/(8*k+1) - 2/(8*k+4) - \
        1/(8*k+5) - 1/(8*k+6))

print("圆周率值是:{}".format(pi))

  

2、蒙特卡罗方法计算 

蒙特卡罗方法(撒点):圆周率本身就是一个圆形,相对于一个正方形来说,相当于圆的面积除以正方形的面积,这个面积之商与圆周率有关系 

  • 圆的面积如何计算?
  • 对一个区域面积向它撒点,每给一个撒点,它随机的可能会出现在这个区域中的任何一个位置上,若撒点的数量十分庞大,而且每一个点又尽可能地随机,那么在圆的面积内部的点就构成了圆的面积,而在整个正方形中的所有撒点就是正方形的面积
  • 通过点的数量与整个圆方形中的撒点数量的比值,就能够计算出圆的面积

代码:

# CalPiV2.py(通过蒙特卡罗方法计算圆周率的值)

from random import random
from time import perf_counter  # perf_counter函数能够对程序运行进行计时

DARTS = 1000*1000   # 当前在区域中抛撒点的总数量,为100万
hits = 0.0  # 目前在圆的内部的点的数量
start = perf_counter()  # 当前系统时间的一个值,启动计时

# 循环撒点的过程,可以描述为一次遍历循环的过程
for i in range(1,DARTS+1):   # 对所有点进行抛撒
    x,y = random(),random()  # 使用x,y变量生成两个随机数的坐标值,random函数返回的是0-1之间的小数值
    dist = pow(x**2+y**2,0.5)  # 使用这个点到圆心的距离判断其是否在圆内
    if dist <= 1.0:  # 这个点在圆的内部
        hits = hits+1   # 经过撒点之后,在圆的内部出现的点的数量
pi = 4* (hits/DARTS)
print("圆周率值是:{}".format(pi))
print("运行时间是:{:.5f}s".format(perf_counter()-start))

 

未用公式,只用计算机、随机方式就可以计算pi 

3、举一反三

  • 一个程序,它的主要运行时间都花在循环上,利用time库的perf_counter方法初步掌握简单的程序性能分析方法
  • 在工程中有很多通过蒙特卡罗方法(随机方法)来进行应用的场景

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cheer-ego

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值