2022年 11月 9日

python学习实验报告(第七周)

一、实验目的

1. 掌握:字符串格式化方法;

2. 掌握:Python中有关文件读写的方法;

3. 掌握:与文件相关的函数与标准库的用法;

4. 掌握:内置函数open()用法,熟练运用with关键字;

5. 掌握:os、os.path、shutil标准库中常用函数的用法。

二、实验内容及结果

1. 从键盘输入一些字符,逐个把它们写到指定的文件,直到输入一个@为止。 示例1: 请输入文件名: out.txt 请输入字符串: Python is open.@ 执行代码后,out.txt文件中内容为: Python is open.

file = input("请输入文件名: ")
string = input("请输入字符串: ")
with open(file, 'w+', encoding='utf-8') as f:
    for s in string:
        if s == "@":
            break
        f.write(s)
    f.seek(0)
    print("写入结果:", f.read())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

图片描述

2. 老王的血压有些高,医生让家属给老王测血压。老王的女儿记录了一段时间的血压测量值,在文件xueyajilu.txt中,内容示例如下:

  • 2020/7/2 6:00,140,82,136,90,69
  • 2020/7/2 15:28,154,88,155,85,63
  • 2020/7/3 6:30,131,82,139,74,61
  • 2020/7/3 16:49,145,84,139,85,73
  • 2020/7/4 5:03,152,87,131,85,63; 文件内各部分含义如下: 测量时间,左臂高压,左臂低压,右臂高压,右臂低压,心率 根据题意,实现下述功能。
    (1)使用字典和列表类型进行数据分析,获取老王的左臂和右臂血压情况的对比表,输出到屏幕上,请注意每列对齐:
  • 低压最高值
  • 左臂和右臂的血压平均值
  • 左臂和右臂的高压差平均值、低压差平均值
  • 心率的平均值
  • (2)上述显示的五个项目,如果左臂有大于50%的项目高于右臂,则输出“结论:左臂血压偏高”;如果等于50%的项目高于右臂,则输出“结论:左臂血压与右臂血压相当”;如果小于50%的项目高于右臂,则输出“结论:右臂血压偏高”。
with open("xieyajilu.txt", 'r', encoding='utf-8') as f:
    rec_name_list = ["测量时间", "左臂高压", "左臂低压", "右臂高压", "右臂低压", "心率"]
    rec_list = []
    for line in f.readlines():
        if line == '\n':
            continue
        record = line.replace('\n', '').strip().split(',')
        rec_list.append({rec_name_list[i]: record[i] for i in range(len(rec_name_list))})

cmp = []
rec_num = len(rec_list)
arm = ["左臂", "右臂"]
# 低压最高值
cmp.append(list(map(lambda a: max([eval(rec_list[i][a+"低压"]) for i in range(rec_num)]), arm)))
# 血压平均值
cmp.append(list(map(lambda a: sum([(eval(rec_list[i][a+"高压"])+eval(rec_list[i][a+"低压"])*2)/3 for i in range(rec_num)])/rec_num, arm)))
# 高压平均值
cmp.append(list(map(lambda a: sum([eval(rec_list[i][a+"高压"]) for i in range(rec_num)])/rec_num, arm)))
# 低压平均值
cmp.append(list(map(lambda a: sum([eval(rec_list[i][a+"低压"]) for i in range(rec_num)])/rec_num, arm)))
# 高低压差平均值
cmp.append(list(map(lambda a: sum([eval(rec_list[i][a+"高压"])-eval(rec_list[i][a+"低压"]) for i in range(rec_num)])/rec_num, arm)))
# 心率的平均值
h_rate_avg = sum([eval(rec_list[i]["心率"]) for i in range(rec_num)]) / rec_num

l_state = 0
obj = ["低压最高值", "血压平均值", "高压平均值", "低压平均值", "压差平均值"]
print('{:<15}{:<15}{:<15}'.format("对比项", "左臂", "右臂"))
for i in range(len(cmp)):
    print('{:<15}{:<15}{:<15}'.format(obj[i], round(cmp[i][0], 1), round(cmp[i][1]), 1))
    if cmp[i][0] > cmp[i][1]:
        l_state += 1
if l_state/len(cmp) > 0.5:
    print("结论:左臂血压偏高")
elif l_state/len(cmp) == 0.5:
    print("结论:左臂血压与右臂血压相当")
else:
    print("结论:右臂血压偏高")

print("心率的平均值", h_rate_avg)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

图片描述

3. 假设当前目录下有一个文件名为class_score.txt的文本文件,存放着某班学生的学号(第1列)、语文成绩(第2列)和数学成绩(第3列),以空格分割各列数据。请编写程序完成下列要求:

  • (1)分别求出这个班语文成绩和数学成绩的平均分(保留1位小数)并输出。
  • (2)找出这个班两门课都不及格(<60)的学生,输出这些学生的学号、语文成绩和数学成绩。
  • (3)找出这个班两门课的平均成绩为优秀(≥90分)的学生,输出这些学生的学号、语文成绩、数学成绩和平均成绩。 程序运行效果如图所示。 图片描述

图片描述

with open("class_score.txt", 'r', encoding='utf-8') as f:
    rec_name_list = ["学号", "语文成绩", "数学成绩"]
    rec_list = []
    print("班级成绩信息如下:")
    for line in f.readlines():
        if line == '\n':
            continue
        print(line, end='')
        record = line.replace('\n', '').strip().split(' ')
        rec_list.append({rec_name_list[i]: record[i] for i in range(len(rec_name_list))})
    print("\n")

rec_num = len(rec_list)
chinese_avg = sum([eval(rec_list[i]["语文成绩"]) for i in range(rec_num)])/rec_num
math_avg = sum([eval(rec_list[i]["数学成绩"]) for i in range(rec_num)])/rec_num
print("全班语文成绩的平均分为{},数学成绩的平均分为{}".format(round(chinese_avg, 1), round(math_avg, 1)))
print("两门课都不及格的学生信息如下:")
for rec in rec_list:
    if eval(rec["语文成绩"]) < 60 and eval(rec["数学成绩"])< 60:
        print(" ".join([rec[k] for k in rec]))
print("两门课成绩的平局分在90分以上的学生信息如下:")
for rec in rec_list:
    rec_avg = (eval(rec["语文成绩"])+eval(rec["数学成绩"])) / 2
    if rec_avg > 90:
        print(" ".join([rec[k] for k in rec]), end=' ')
        print(rec_avg)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

图片描述

4. 编写程序,打开任意的文本文件,在指定的位置产生一个相同文件的副本,即实现文件的拷贝功能。

import shutil
import os

input_file = input("请输入要拷贝的文本文件:")
input_filename = os.path.basename(input_file)
output_path = input("请输入拷贝的目标路径:")
output_file = os.path.join(output_path, input_filename)
try:
    shutil.copyfile(input_file, output_file)
    print("写入成功")
except:
    print("写入失败")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

图片描述

图片描述

5. 在自己电脑任一盘符中新建以OS_Test命名的文件夹,并在该文件夹中新建以.doc .bmp .txt .png .jpeg .xlsx为扩展名的文件若干,请写一个程序,删除掉OS_Test目录里面(不包含子目录)所有的扩展名为.txt的文件,并将删除掉的文件名称打印出来。

import os

directory = os.listdir(r"D:\OS_Test")
print("文件夹中的文件有", "  ".join(directory))
for f in directory:
    ext = os.path.splitext(f)[1]
    if ext == ".txt":
        os.remove(os.path.join(r"D:\OS_Test", f))
        print("删除文件:", f)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

图片描述

三、实验小结

虽说本周题型针对的是文件的操作,但是感觉难度主要还是在于文件内容的处理。文件处理的操作相对来说还是比较简单的,对于文件的各种操作,以我目前的经历以及水平来说,使用到的次数不是很多,但是个人认为很多操作都是可以简单地理解并掌握的。此次作业的题目解法相对较多,而我在解题过程中,大都力求的是以容易理解的代码来解答,虽说用到一些平时用得较少也不太擅长用的方法,但是这确实是从了解到掌握的必经过程。