实验三 选择与循环结构
一、实验学时: 2学时
二、实验目的
- 理解条件表达式与True/False的等价关系
- 熟练运用常见选择结构
- 熟练运用for循环和while循环
- 理解带else子句的循环结构执行过程
- 理解break和continue语句在循环中的作用
三、 实验内容
- 编写程序,计算小于1000的所有整数中能够同时被5和7整除的最大整数。
- 编写程序,计算1+2+。。。+100的和。
- 编写程序输出100以内的素数。
- 编写程序,实现抓狐狸游戏。假设墙上有5个洞(编号分别为0、1、2、3、4),其中一个洞里有狐狸,人类玩家输入洞口编号,如果洞里有狐狸就抓到了;如果洞里没有狐狸就第二天再来抓。但在第二天人类玩家来抓之前,狐狸会跳到隔壁的洞里。
- 小明单位发了100元的购物卡,小明到超市买三类洗化用品,洗发水(15元),香皂(2元),牙刷(5元)。要把100元正好花掉,可有哪些购买结合?
- 求两个数的最大公约数和最小公倍数。(提示:公约数一定小于等于两数中的小的那个数,且能同时被两个数整除;公倍数一定大于等于两数中的大数,且是大数的倍数又能被两数中的小数整除)
- 编写程序,求1!+3!+5!+7!+9!。
- 编写程序,让用户输入一个整数,如果输入的是正数就输出1,如果输入的是负数就输出-1,否则输出0。
- 输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。
- 某百货公司为了促销,采用购物打折的办法。1000元以上者,按九五折优惠;2000元以上者,按九折优惠;3000元以上者,按八五折优惠;5000元以上者,按八折优惠。编写程序,输入购物款数,计算并输出优惠价。
四、实验结果
- 编写程序,计算小于1000的所有整数中能够同时被5和7整除的最大整数。
题目思路:找最大整数,可以利用循环从1000开始倒着找能同时被5和7整除的数,找到的第一个符合条件的数即为最大整数 。
程序代码:
"""
程序名:实验3.1.py
功能:编写程序,计算小于1000的所有整数中能够同时被5和7整除的最大整数。
日期:2022.3.28
版本:1.0
"""
for i in range(1000, 0, -1): # 可以倒着从1000~1开始遍历
if i % 7 == 0 and i % 5 == 0: # 同时满足整除7和5
print(i)
break # 找到第一个即为最大,跳出循环
运行结果截图:
- 编写程序,计算1+2+。。。+100的和。
题目思路:
可以用列表生成式生成含有1-100的数的列表,然后用sum函数算总和。
程序代码:
"""
程序名:实验3.2.py
功能:编写程序,计算1+2+。。。+100的和。
日期:2022.3.28
版本:1.0
"""
print(sum([i for i in range(1, 101)])) # 列表生成式生成含有1-100的数的列表然后用sum函数
运行结果截图:
- 编写程序输出100以内的素数。
题目思路:
通过循环遍历2到100的数i,如果数i有2到i-1的因子 ,说明他不是素数,跳出循环,继续下一个数,如果没有,则输出。
程序代码:
"""
程序名:实验3.3.py
功能:编写程序输出100以内的素数。
日期:2022.3.28
版本:1.0
"""
for i in range(2, 101): # 素数范围是2~100
for j in range(2, i): # 判断2~i-1是否有能整除的因子
if i % j == 0: # 如果有,直接跳出循环
break
else:
print(i, end=' ') # 如果没有则打印
运行结果截图:
- 编写程序,实现抓狐狸游戏。假设墙上有5个洞(编号分别为0、1、2、3、4),其中一个洞里有狐狸,人类玩家输入洞口编号,如果洞里有狐狸就抓到了;如果洞里没有狐狸就第二天再来抓。但在第二天人类玩家来抓之前,狐狸会跳到隔壁的洞里。
题目思路:
首先定义洞的值为0~4的列表,利用random.randint函数随机生成狐狸位置,接着在循环中让用户输入关键字guess即猜的位置,如果猜对,则胜利,没猜对,则狐狸+1或-1,在第一个或最后一个位置只能+1和-1一种,然后再次循环。直到胜利。注意要检验用户输入洞的编号是否正确。
程序代码:
"""
程序名:实验3.4.py
功能:编写程序,实现抓狐狸游戏。
假设墙上有5个洞(编号分别为0、1、2、3、4),
其中一个洞里有狐狸,人类玩家输入洞口编号,如果洞里有狐狸就抓到了;
如果洞里没有狐狸就第二天再来抓。
但在第二天人类玩家来抓之前,狐狸会跳到隔壁的洞里。
日期:2022.3.28
版本:1.0
"""
import random
hole = [0, 1, 2, 3, 4]
fox = random.randint(0, 4) # 狐狸随机位置生成
while 1:
guess = int(input("请输入洞口编号:"))
if guess < 0 or guess > 4:
print("没有那个洞!")
elif guess == hole[fox]:
print("你抓到狐狸了!")
break
else:
print("你没抓到狐狸!")
if fox == 0:
fox += 1 # 第一个洞只能跳到第二个
if 0 < fox < 4:
fox += random.choice([-1, 1]) # 从[-1,1]中随机选取一个数
if fox == 5:
fox -= 1 # 第五个洞只能跳到第四个
运行结果截图:
- 小明单位发了100元的购物卡,小明到超市买三类洗化用品,洗发水(15元),香皂(2元),牙刷(5元)。要把100元正好花掉,可有哪些购买结合?
题目思路:
利用每个物品最多的购买个数进行循环条件,三重循环,最后一重循环中加入if条件,满足3种物品价格之和为100,即输出方案。
程序代码:
"""
程序名:实验3.5.py
功能:小明单位发了100元的购物卡,小明到超市买三类洗化用品,
洗发水(15元),香皂(2元),牙刷(5元)。要把100元正好花掉,可有哪些购买结合?
日期:2022.3.28
版本:1.0
"""
money = 100 # 初始100块钱
i = 1 # 计数:购买方案
for x in range(6): # 洗发水最多6
for y in range(50): # 香皂最多50
for z in range(20): # 牙刷最多5
if 15 * x + 2 * y + 5 * z == 100: # 如果刚好满足100块钱
print(f'第{i}种方案:洗发水x{x},香皂x{y},牙刷x{z}') # 格式化输出方案
i += 1
运行结果截图:
- 求两个数的最大公约数和最小公倍数。(提示:公约数一定小于等于两数中的小的那个数,且能同时被两个数整除;公倍数一定大于等于两数中的大数,且是大数的倍数又能被两数中的小数整除)
题目思路:
最大公约数可以使用欧几里得算法,即辗转相除进行实现。本题可以使用递归去实现。而求出最大公约数后,两个数的最小公倍数等于两个数相乘除以最大公约数。
程序代码:
"""
程序名:实验3.6.py
功能:求两个数的最大公约数和最小公倍数。
(提示:公约数一定小于等于两数中的小的那个数,且能同时被两个数整除;
公倍数一定大于等于两数中的大数,且是大数的倍数又能被两数中的小数整除)
日期:2022.3.28
版本:1.0
"""
# 最大公约
def gcd(a, b):
return gcd(b, a % b) if (a % b) else b # 辗转相除法求最大公约 套用三目运算符简化代码
# 最小公倍
def lcm(a, b):
return a * b / gcd(a, b) # 最小公倍数 = a * b / 最大公约数
a = int(input("请输入a:"))
b = int(input("请输入b:"))
print(f'a,b的最大公约数是{gcd(a,b)} 最小公倍数是{int(lcm(a,b))}')
运行结果截图:
- 编写程序,求1!+3!+5!+7!+9!。
题目思路:
阶乘可以用递归函数来算,然后1.3.5.7.9即为奇数1-9,可以设置步长为2。
程序代码:
"""
程序名:实验3.7.py
功能:求1!+3!+5!+7!+9!。
日期:2022.3.31
版本:1.0
"""
def factorial(n): # 利用递归计算阶乘
if n == 0: # 递归结束条件
return 1
else:
return n * factorial(n - 1)
sum1 = 0
for i in range(1, 10, 2): # 计算1-9步长为2,阶乘的和
sum1 += factorial(i)
print(sum1)
运行结果截图:
- 编写程序,让用户输入一个整数,如果输入的是正数就输出1,如果输入的是负数就输出-1,否则输出0。
题目思路:
if-elif嵌套即可,注意题目要求输入整数,判断一下即可。
程序代码:
"""
程序名:实验3.8.py
功能:让用户输入一个整数,如果输入的是正数就输出1,如果输入的是负数就输出-1,否则输出0。
日期:2022.3.31
版本:1.0
"""
num = eval(input("请输入一个整数:"))
if type(num) != int: # 判断数据合法性
print("输入的不是整数!")
elif num > 0: # 正数输出1
print(1)
elif num < 0: # 负数输出-1
print(-1)
else: # 否则输出0
print(0)
运行结果截图:
- 输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。
题目思路:
python自带的isalpha(),isspace(),isdigit()函数可以判断是否为字母、空格和数字。利用if来判断,最后其他字符即为总数减去英文字母,空格,数字和其他字符。
程序代码:
"""
程序名:实验3.9.py
功能:输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。
日期:2022.3.31
版本:1.0
"""
chars = input("请输入一行字符:")
alphabet = 0
space = 0
digit = 0
otherC = 0
for i in chars:
if i.isalpha(): # isalpha()判断是否为字母
alphabet += 1
elif i.isspace(): # isspace()判断是否为空格
space += 1
elif i.isdigit(): # isdigit()判断是否为数字
digit += 1
else:
otherC += 1 # 剩下的即为其他字符
print(f'英文字母有{alphabet}个,空格有{space}个,数字有{digit}个,其他字符有{otherC}个')
运行结果截图:
- 某百货公司为了促销,采用购物打折的办法。1000元以上者,按九五折优惠;2000元以上者,按九折优惠;3000元以上者,按八五折优惠;5000元以上者,按八折优惠。编写程序,输入购物款数,计算并输出优惠价。
题目思路:
根据if-elif判断价格给discount赋值,最后计算优惠价并输出即可。注意数据合法性。
程序代码:
"""
程序名:实验3.10.py
功能:某百货公司为了促销,采用购物打折的办法。
1000元以上者,按九五折优惠;
2000元以上者,按九折优惠;
3000元以上者,按八五折优惠;
5000元以上者,按八折优惠。
编写程序,输入购物款数,计算并输出优惠价。
日期:2022.3.31
版本:1.0
"""
cost = eval(input("请输入购物款数:"))
discount = 1
if cost < 0:
print("数据不合法!")
elif 0 <= cost <= 1000:
discount = 1
elif 1000 < cost <= 2000:
discount = 0.95
elif 2000 < cost <= 3000:
discount = 0.9
elif 3000 < cost <= 5000:
discount = 0.85
elif 5000 < cost:
discount = 0.8
if cost >= 0:
print("优惠价为:{:.1f}元".format(cost * discount))
运行结果截图:
五、实验小结
问题与解决方法:
1.在编写狐狸游戏时,如果没抓到狐狸,狐狸会左右选一个洞,也就是随机+1或-1,不知道如何实现。
解决方法:通过查询random库中函数,找到一个choice函数,该函数表示从序列中随机选取一个元素,因此将-1和+1存入列表中,用choice去随机选取,达到狐狸位置随机+1或-1的效果。
2.使用range时想倒着遍历,输入range(1000, 0)却不正确。
解决方法:通过翻书深刻认识range函数,得知倒着遍历时需要设置步长。即range(1000,0,-1)。
3.提示SyntaxError: invalid syntax
解决方法:查询得知为无效语法,检查后得知是变量名使用了关键字。
4.提示TypeError: ‘xxx’ object is not iterable
解决方法:查询得知是对象不可被迭代的意思,通过上网查询得知,常见的可迭代对象包括:字符串类型,列表,元组和字典。剩下的一些类型,比如:int类型,float类型,布尔类型和None就不是可迭代对象。
心得体会:
1.即使像python这样简洁的语言,也需要仔细的检查某些细枝末节的错误,如注意大小写,是否使用关键字作为变量名。有时候一个缩进错误,程序就不能正常运行,因此在写代码时要小心谨慎。
2.在学习python的过程中,要学会利用手上的书,在遇到想不出方法的题目时,可以翻看书上类似例题,进行解答。同时,在做题的过程中,如果有了思路但代码不知道如何实现,可以通过上网查询来解决,如不知道如何随机+1或-1,可以通过上网查询random库中函数,来找到符合自己思路的函数去使用。