期末模拟练习(机房版)

一、读程序写结果(共5题)

请阅读以下程序,写出运行结果。


第1题(字典遍历与条件判断)

python 复制代码
# 创建字典 dd,包含4个学号-身高键值对
dd = {'101': 161, '102': 167, '103': 157, '104': 160}
# 声明整型变量 t 和 r,均赋值为 0
t = r = 0
# for 循环:遍历字典 dd 的 items()(键值对)
for x, y in dd.items():
    # 判断 y 是否大于 t
    if y > t:
        # 将 y 的值赋给 t,将 x 的值赋给 r
        t = y
        r = x
# print() 输出内容到屏幕上
print(r, t)

答案

复制代码
102 167

解析

  • 代码目的是寻找字典中值(value)最大的项
  • 初始 t=0,遍历过程:
    • '101': 161 > 0t=161, r='101'
    • '102': 167 > 161t=167, r='102'
    • '103': 157 → 不大于 t,不变
    • '104': 160 → 不大于 t,不变
  • 最终输出键 '102' 和值 167

第2题(集合运算)

python 复制代码
# 创建集合 set1,包含三个元素
set1 = {'Python', 'C', 'Java'}
# 创建集合 set2,包含三个元素
set2 = {'C++', 'Java', 'Python'}
# 对称差集运算:取两个集合中不重复的元素
print(set1 ^ set2)
# 并集运算:取两个集合的并集
print(set1 | set2)

答案

复制代码
{'C', 'C++'}
{'C', 'Java', 'C++', 'Python'}

解析

  • ^ 是对称差集(Symmetric Difference),即两个集合中不重复的元素。共同元素是 'Python''Java',排除后剩下 'C''C++'
  • | 是并集(Union),即两个集合所有元素的合集。结果为 {'Python', 'C', 'Java', 'C++'}
  • 注意:集合是无序的,输出顺序可能不同,但包含的元素必须一致

第3题(字符串分割与索引)

python 复制代码
# 声明字符串变量 str,赋值为 "apple orange banana"
str = "apple orange banana"
# 使用 split() 按空格分割字符串,返回列表
ls = str.split()
# print() 输出内容到屏幕上
# 访问列表 ls 的最后一个元素(负索引-1)
print(ls[-1])

答案

复制代码
banana

解析

  • split() 默认按空格分割字符串,生成列表 ['apple', 'orange', 'banana']
  • ls[-1] 取列表最后一个元素,即 'banana'

第4题(函数参数传递------列表可变性)

python 复制代码
# 定义函数 f1,接收参数 x
def f1(x):
    # 将 x 重新赋值为新列表(创建新对象)
    x = [-1, 2, 3, -4]

# 创建列表 ls,包含三个元素
ls = ['a1', 'b1', 5]
# 调用 f1 函数,将 ls 作为参数传入
f1(ls)
# print() 输出内容到屏幕上
print("ls的值为:", ls)

答案

复制代码
ls的值为: ['a1', 'b1', 5]

解析

  • 在 Python 中,列表是可变对象,通常作为引用传递
  • 但是,函数内部执行了 x = [-1, 2, 3, -4],这是一个赋值操作
  • 它在函数内部创建了一个新的局部列表对象,并将变量 x 指向它
  • 这并不会修改原列表 ls 的内容(如果是 x[0] = ... 则会修改)
  • 因此,外部的 ls 不受影响,保持原样

第5题(异常处理)

python 复制代码
# 导入 math 模块
import math
# 声明整型变量 s,赋值为 0
s = 0
# try-except-else 异常处理结构
try:
    # 创建列表 n,包含三个元素
    n = [4, 16, -9]
    # for 循环:遍历 range(len(n)) 中的每个元素
    for i in range(len(n)):
        # 计算 n[i] 的平方根,累加到 s 中
        s = s + math.sqrt(n[i])
# 捕获所有异常
except:
    # 输出错误提示
    print('Error!')
# 未发生异常时执行
else:
    # print() 输出内容到屏幕上
    print(s)

答案

复制代码
Error!

解析

  • 循环遍历列表 n
  • i=0 时,math.sqrt(4) = 2.0s = 2.0
  • i=1 时,math.sqrt(16) = 4.0s = 6.0
  • i=2 时,n[2]-9math.sqrt(-9) 会引发 ValueError(数学域错误)
  • 程序跳转到 except 块,打印 'Error!'
  • 由于发生了异常,else 块不会执行

二、补全程序题(共2题)

请在下划线处填上正确的代码,使程序完整且能正常运行。


第1题(二分查找算法)

实现函数 binary_search,采用二分查找法,在给定的升序查找表中查找给定的待查对象。若存在则返回下标,不存在则返回 None

python 复制代码
# 定义函数 binary_search,接收两个参数:L(查找表)、s(待查对象)
def binary_search(L, s):
    # 声明整型变量 low,赋值为 0
    # 声明整型变量 high,赋值为 列表长度减1
    low, high = 0, len(L) - 1
    # while 循环:当 low <= high 时继续
    while low <= high:
        # 计算中间位置 mid,为 (________) // 2
        mid = ________
        # 判断 L[mid] 是否等于 s
        if L[mid] == s:
            # 找到目标,________
            ________
        # 判断 L[mid] 是否小于 s
        elif L[mid] < s:
            # 在右半部分继续查找
            low = mid + 1
        # 否则(L[mid] > s)
        else:
            # 在左半部分继续查找
            ________
    # 未找到,返回 None
    return None

# 创建有序列表 arr
arr = [1, 3, 5, 7, 9, 11, 13]
# 调用 binary_search 查找 7 的下标
print(binary_search(arr, 7))

答案

  • 第1空:(low + high) // 2
  • 第2空:return mid
  • 第3空:high = mid - 1

解析

  • 二分查找每次将查找范围缩小一半
  • mid = (low + high) // 2 计算中间位置(整数除法)
  • 找到目标时直接 return mid 返回下标
  • 当中间值大于待查对象时,将 high 设为 mid - 1,在左半部分继续查找
  • low > high 时循环结束,说明未找到,返回 None

第2题(三角形面积计算------含异常处理)

实现函数 get_area(a,b,c),根据三边长求三角形面积。当边长无法构成三角形时(海伦公式根号内为负),捕获 ValueError 并返回空值。

python 复制代码
# 从 math 模块导入 sqrt 函数
from math import sqrt

# 定义函数 get_area,接收三个参数 a、b、c(三边长)
def get_area(a, b, c):
    # ________ 异常处理结构
    ________
        # 计算半周长 h
        h = (a + b + c) / 2
        # 使用海伦公式计算面积
        area = sqrt(h * (h - a) * (h - b) * (h - c))
    # 捕获 ________ 异常
    except ________:
        # 输出提示信息
        print("非法的三角形边长!")
        # 返回 ________
        return ________
    # 返回三角形的面积
    return area

# 调用 get_area,传入边长(1, 2, 5)
area2 = get_area(1, 2, 5)
# print() 输出内容到屏幕上
print("边长(1,2,5)的面积:", area2)

答案

  • 第1空:try:
  • 第2空:ValueError
  • 第3空:None

解析

  • 海伦公式中,如果边长不能构成三角形,根号内的 h*(h-a)*(h-b)*(h-c) 会为负数
  • sqrt() 接收负数时会引发 ValueError
  • 使用 try-except 捕获异常,发生异常时返回 None 表示无结果
  • 正常情况返回计算出的面积

三、程序设计题(共6题)

请编写完整程序解决以下问题。每题附参考代码(带逐行注释)。


第1题(农田喷灌系统计算)

已知喷灌强度为 5 mm/h,土壤有效持水量为 200 mm/m,当前含水率为 55%,适宜含水量下限为 70%。

从键盘依次输入:长(m)、宽(m)、耕作层深度(m)。

要求:

  1. 计算需要灌溉的水量(立方米),结果保留2位小数
  2. 每天工作6小时,计算需要多少天完成(向上取整)

参考代码

python 复制代码
# 导入 math 模块(用于向上取整)
import math

# 已知常量
irrigation_rate = 5               # 喷灌强度:5 mm/h
water_holding = 200               # 土壤有效持水量:200 mm/m
current_rate = 0.55               # 当前含水率:55%
target_rate = 0.70                # 适宜下限含水率:70%
hours_per_day = 6                 # 每天工作6小时

# input() 输入内容到控制台,并转换为浮点数
length = float(input("请输入长(m):"))
width = float(input("请输入宽(m):"))
depth = float(input("请输入耕作层深度(m):"))

# 计算面积
area = length * width
# 计算总持水能力(mm)
total_capacity = water_holding * depth
# 计算需补充的深度(mm)
need_depth = total_capacity * (target_rate - current_rate)
# 计算需灌溉水量(立方米):1mm水深在1m²上等于0.001m³
water_volume = area * need_depth * 0.001

# 输出需灌溉水量(保留2位小数)
print(f"需灌溉水量:{water_volume:.2f} 立方米")

# 计算每天喷灌深度(mm)
daily_depth = irrigation_rate * hours_per_day
# 计算所需天数(向上取整)
days = math.ceil(need_depth / daily_depth)

# 输出所需天数
print(f"需要 {days} 天完成灌溉")

输出结果(示例输入:长100m、宽50m、深度0.3m):

复制代码
请输入长(m):100
请输入宽(m):50
请输入耕作层深度(m):0.3
需灌溉水量:45.00 立方米
需要 4 天完成灌溉

第2题(红富士苹果分级)

红富士苹果根据横径大小划分等级:

  • ≥ 80mm:特等果
  • 70mm ≤ 横径 < 80mm:一等果
  • 60mm ≤ 横径 < 70mm:二等果
  • 横径 < 60mm:等外果

从键盘输入10个苹果的横径(mm),统计并输出各等级的数量。

参考代码

python 复制代码
# 声明整型变量 a1~a4,分别统计特等、一等、二等、等外果数量,均初始化为0
a1 = a2 = a3 = a4 = 0

# for 循环:遍历 range(10) 中的每个元素(循环10次)
for i in range(10):
    # input() 输入内容到控制台,并转换为浮点数
    d = float(input("请输入苹果横径(mm):"))
    # 判断横径是否 ≥ 80
    if d >= 80:
        # 特等果计数加1
        a1 += 1
    # 判断横径是否在 70~80 之间
    elif d >= 70:
        # 一等果计数加1
        a2 += 1
    # 判断横径是否在 60~70 之间
    elif d >= 60:
        # 二等果计数加1
        a3 += 1
    # 其余为等外果
    else:
        # 等外果计数加1
        a4 += 1

# 输出各等级苹果数量
print(f"特等果:{a1}个")
print(f"一等果:{a2}个")
print(f"二等果:{a3}个")
print(f"等外果:{a4}个")

输出结果(示例):

复制代码
请输入苹果横径(mm):85
请输入苹果横径(mm):72
请输入苹果横径(mm):65
请输入苹果横径(mm):58
...
特等果:3个
一等果:4个
二等果:2个
等外果:1个

第3题(律师案件分段计费)

某律师按案件金额分段计费,标准如下:

  • ≤ 10000 元:收费 50 元
  • 10001 ~ 100000 元:超出 10000 元部分按 2.5%
  • 100001 ~ 200000 元:超出 100000 元部分按 2%
  • 200000 元:超出 200000 元部分按 1.5%

输入案件数 n,循环输入每个案件的金额,输出每个案件的费用及总收入。

参考代码

python 复制代码
# input() 输入内容到控制台,并转换为整数
n = int(input("请输入案件数:"))
# 声明浮点变量 total_income,赋值为 0(总收入)
total_income = 0

# for 循环:遍历 range(n) 中的每个元素
for i in range(n):
    # input() 输入内容到控制台,并转换为浮点数
    amount = float(input("请输入案件金额:"))
    # 判断金额是否 ≤ 10000
    if amount <= 10000:
        fee = 50
    # 判断金额是否 ≤ 100000
    elif amount <= 100000:
        fee = 50 + (amount - 10000) * 0.025
    # 判断金额是否 ≤ 200000
    elif amount <= 200000:
        fee = 50 + 90000 * 0.025 + (amount - 100000) * 0.02
    # 金额 > 200000
    else:
        fee = 50 + 90000 * 0.025 + 100000 * 0.02 + (amount - 200000) * 0.015
    # 输出当前案件费用(保留2位小数)
    print(f"案件{i+1}费用:{fee:.2f}元")
    # 累加总收入
    total_income += fee

# 输出总收入(保留2位小数)
print(f"总收入:{total_income:.2f}元")

输出结果(示例):

复制代码
请输入案件数:3
请输入案件金额:5000
案件1费用:50.00元
请输入案件金额:50000
案件2费用:1050.00元
请输入案件金额:300000
案件3费用:5300.00元
总收入:6400.00元

第4题(勾股数查找)

找出满足 a² + b² = c² 的正整数三元组 (a, b, c),且 a < b < 50c 为整数。

参考代码

python 复制代码
# for 循环:遍历 range(1, 50) 中的每个元素(a从1到49)
for a in range(1, 50):
    # for 循环:遍历 range(a + 1, 50) 中的每个元素(b从a+1到49)
    for b in range(a + 1, 50):
        # 计算 c 的平方值
        c_square = a * a + b * b
        # 计算 c 的平方根
        c = c_square ** 0.5
        # 判断 c 是否为整数(c 等于其整数部分)
        if c == int(c):
            # 输出找到的勾股数三元组
            print(f"({a}, {b}, {int(c)})")

输出结果

复制代码
(3, 4, 5)
(5, 12, 13)
(6, 8, 10)
(7, 24, 25)
(8, 15, 17)
(9, 12, 15)
(9, 40, 41)
(10, 24, 26)
(11, 60, 61)
(12, 16, 20)
(12, 35, 37)
(13, 84, 85)
(14, 48, 50)
(15, 20, 25)
(15, 36, 39)
(16, 30, 34)
(16, 63, 65)
(18, 24, 30)
(18, 80, 82)
(20, 21, 29)
(20, 48, 52)
(21, 28, 35)
(21, 72, 75)
(24, 32, 40)
(24, 45, 51)
(25, 60, 65)
(27, 36, 45)
(28, 45, 53)
(30, 40, 50)
(33, 44, 55)
(36, 48, 60)

另一种解法(使用 math.isclose)

python 复制代码
import math

for a in range(1, 50):
    for b in range(a + 1, 50):
        c = math.sqrt(a * a + b * b)
        if math.isclose(c, round(c)):
            print(f"({a}, {b}, {round(c)})")

第5题(瘟疫感染模拟)

某种传染病传染规律如下:

  • 第0天:初始感染1株
  • 第1天起:每天新增感染数等于前一天的感染数
  • 政府可能在某个天数介入,介入后每天新增感染数 = 前一天新增数 × 0.1(保留整数)
  • 若某天感染总数清零,则输出清零天数;否则输出最终未清零及感染数

输入天数限制 days 及政府介入天数 day0(1 ≤ day0 ≤ days),模拟输出过程。

参考代码

python 复制代码
# input() 输入内容到控制台,并转换为整数
days = int(input("请输入天数限制:"))
day0 = int(input("请输入政府介入天数(1~days):"))

# 检查 day0 是否在有效范围内
if day0 < 1 or day0 > days:
    # 输出错误提示,打印 day(未有效执行)
    print("输入无效")
# 执行模拟
else:
    # 声明整型变量 total,赋值为 1(初始感染株数)
    total = 1
    # 声明整型变量 new_add,赋值为 1(前一天新增数)
    new_add = 1
    # 声明整型变量 day,赋值为 0(天数计数)
    day = 0

    # 输出第0天信息
    print(f"第{day}天:感染总数 = {total},新增 = {new_add}")

    # for 循环:遍历 range(1, days + 1) 中的每个元素
    for day in range(1, days + 1):
        # 判断是否达到清零条件
        if total <= 0:
            # 输出清零信息
            print(f"第{day}天,感染清零!")
            # 输出清零天数
            print(f"清零天数:{day}")
            # 结束程序
            break
        # 判断是否已到政府介入天数
        if day >= day0:
            # 政府介入后,新增数 = 前一天新增数 × 0.1(取整)
            new_add = int(new_add * 0.1)
        # 更新感染总数:累加新增数
        total += new_add
        # 输出当天信息
        print(f"第{day}天:感染总数 = {total},新增 = {new_add}")

    # 如果循环正常结束(未 break),说明未清零
    else:
        # 输出最终感染数
        print(f"监测期结束,最终感染株数 = {total}")

输出结果(示例:days=15, day0=5):

复制代码
请输入天数限制:15
请输入政府介入天数(1~days):5
第0天:感染总数 = 1,新增 = 1
第1天:感染总数 = 2,新增 = 1
第2天:感染总数 = 3,新增 = 1
第3天:感染总数 = 4,新增 = 1
第4天:感染总数 = 5,新增 = 1
第5天:感染总数 = 6,新增 = 0(政府介入,新增取整为0)
第6天:感染总数 = 6,新增 = 0
...

第6题(销售指数排序 + 文件写入)

某电商平台十大家电品牌的销售指数存放在一个二维列表中,具体为:

复制代码
[["万和", 89.8], ["容声", 91.4], ["老板电器", 88.3], ["科沃斯", 88.7],
 ["米家", 89.1], ["戴森", 91.1], ["美的", 88.8], ["西门子", 92.5],
 ["海尔", 96.6], ["九阳", 90.3]]

请编程用排序算法实现根据各品牌销售指数的升序排列,并将结果写入文件 px.txt 中。

参考代码

python 复制代码
# 原始数据:品牌及销售指数
sales_data = [
    ["万和", 89.8],
    ["容声", 91.4],
    ["老板电器", 88.3],
    ["科沃斯", 88.7],
    ["米家", 89.1],
    ["戴森", 91.1],
    ["美的", 88.8],
    ["西门子", 92.5],
    ["海尔", 96.6],
    ["九阳", 90.3]
]

def selection_sort_asc(data):
    """选择排序(升序),按每个子列表的第2个元素(销售指数)排序"""
    n = len(data)
    # 外层循环:遍历每个位置
    for i in range(n):
        # 假设当前位置为最小值索引
        min_idx = i
        # 内层循环:在未排序部分查找真正的最小值索引
        for j in range(i + 1, n):
            if data[j][1] < data[min_idx][1]:
                min_idx = j
        # 如果最小值索引发生变化,交换两个元素
        if min_idx != i:
            data[i], data[min_idx] = data[min_idx], data[i]

# 执行排序(升序)
selection_sort_asc(sales_data)

# 将排序后的结果写入文件 px.txt
with open("px.txt", "w", encoding="utf-8") as f:
    for brand, score in sales_data:
        # 每行格式:品牌,指数(保留一位小数)
        f.write(f"{brand},{score:.1f}\n")

print("排序完成,结果已写入 px.txt")

输出结果(px.txt 文件内容):

复制代码
老板电器,88.3
科沃斯,88.7
美的,88.8
米家,89.1
九阳,90.3
戴森,91.1
容声,91.4
西门子,92.5
海尔,96.6
万和,89.8

另一种解法(使用 sorted 函数 + lambda)

python 复制代码
sales_data = [
    ["万和", 89.8], ["容声", 91.4], ["老板电器", 88.3],
    ["科沃斯", 88.7], ["米家", 89.1], ["戴森", 91.1],
    ["美的", 88.8], ["西门子", 92.5], ["海尔", 96.6], ["九阳", 90.3]
]

# sorted 返回新列表,不改变原数据
sorted_data = sorted(sales_data, key=lambda x: x[1])

with open("px.txt", "w", encoding="utf-8") as f:
    for brand, score in sorted_data:
        f.write(f"{brand},{score:.1f}\n")

print("排序完成,结果已写入 px.txt")

对比sort() 原地排序(修改原列表),sorted() 生成新列表(不修改原列表)。如果不需要保留原始顺序,用 sort() 更省内存;如果需要保留原始数据,用 sorted()