实验七 文件与文件夹操作

实验七 文件与文件夹操作

一、实验学时:2学时

二、实验目的

  1. 掌握:Python中有关文件读写的方法;
  2. 掌握:与文件相关的函数与标准库的用法;
  3. 掌握:内置函数open()用法,熟练运用with关键字;
  4. 掌握:os、os.path、shutil标准库中常用函数的用法。

三、实验内容

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

  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%的项目高于右臂,则输出“结论:右臂血压偏高”。
  1. 假设当前目录下有一个文件名为class_score.txt的文本文件,存放着某班学生的学号(第1列)、语文成绩(第2列)和数学成绩(第3列),以空格分割各列数据。请编写程序完成下列要求:
  • (1)分别求出这个班语文成绩和数学成绩的平均分(保留1位小数)并输出。
  • (2)找出这个班两门课都不及格(<60)的学生,输出这些学生的学号、语文成绩和数学成绩。
  • (3)找出这个班两门课的平均成绩为优秀(≥90分)的学生,输出这些学生的学号、语文成绩、数学成绩和平均成绩。 程序运行效果如图所示。
    图片描述
  1. 编写程序,打开任意的文本文件,在指定的位置产生一个相同文件的副本,即实现文件的拷贝功能。

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

四、实验结果

1.从键盘输入一些字符,逐个把它们写到指定的文件,直到输入一个@为止。 示例1: 请输入文件名: out.txt 请输入字符串: Python is open.@ 执行代码后,out.txt文件中内容为: Python is open.
题目思路:for循环将字符串变成一个一个字符进行写入,直到遇到@则break即可
程序代码:

"""
程序名:实验7.1.py
功能:从键盘输入一些字符,逐个把它们写到指定的文件,直到输入一个@为止。
示例1: 请输入文件名: out.txt
请输入字符串: Python is open.@
执行代码后,out.txt文件中内容为: Python is open.
日期:2022.5.21
版本:1.0
"""
filename = input("请输入文件名:")
fp = open(filename, 'w')  # 创建文件
print("文件已创建")
string1 = input("请输入字符串:")
for s in string1:
    if s == '@':  # 读到@就停止
        break
    fp.write(s)  # 将字符写入文件中

fp.close()  # 关闭文件
print("文件已关闭")

运行结果截图:
图片描述
图片描述
图片描述

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%的项目高于右臂,则输出“结论:右臂血压偏高”。

题目思路:创建6个列表来存储每次的血压各个数据,然后通过逐行读取文件,用split去分割分别存储到各个列表中,之后用列表进行计算即可。其中注意平均动脉压的计算公式是[收缩压+(舒张压*2)]/3
程序代码:

"""
程序名:实验7.2.py
日期:2022.5.21
版本:1.0
"""
# 读取测量数据
with open('xueyajilu.txt') as fp:
    time, leftHigh, leftLow, rightHigh, rightLow, heart = [], [], [], [], [], []
    i = 0
    for line in fp:
        a = line.strip().split(',')
        time.append(a[0])
        leftHigh.append(int(a[1]))
        leftLow.append(int(a[2]))
        rightHigh.append(int(a[3]))
        rightLow.append(int(a[4]))
        heart.append(int(a[5]))
        i += 1


# 计算低压最高值
def max_lowPress(leftLow1, rightLow1):
    return [max(leftLow1), max(rightLow1)]


# 计算血压平均值
def average_press(leftHigh1, leftLow1, rightHigh1, rightLow1):
    # 平均动脉压的计算公式是[收缩压+(舒张压*2)]/3
    average1 = (sum(leftHigh1) + sum(leftLow1) * 2) / (len(leftLow1) * 2 + len(leftHigh1))
    average2 = (sum(rightHigh1) + sum(rightLow1) * 2) / (len(rightLow1) * 2 + len(rightHigh1))
    return [average1, average2]


# 计算高压平均值
def average_highPress(leftHigh1, rightHigh1):
    average1 = sum(leftHigh1) / len(leftHigh1)
    average2 = sum(rightHigh1) / len(rightHigh1)
    return [average1, average2]


# 计算低压平均值
def average_lowPress(leftLow1, rightLow1):
    average1 = sum(leftLow1) / len(leftLow1)
    average2 = sum(rightLow1) / len(rightLow1)
    return [average1, average2]


# 计算压差平均值
def average_differPress(leftHigh1, leftLow1, rightHigh1, rightLow1):
    average1 = (sum(leftHigh1) - sum(leftLow1)) / len(leftLow1)
    average2 = (sum(rightHigh1) - sum(rightLow1)) / len(rightLow1)
    return [average1, average2]


# 计算心率平均值
def average_heartRate(heart1):
    average = sum(heart1) / len(heart1)
    return average


# 判断血压
def judge_press(leftHigh, leftLow, rightHigh, rightLow):
    i = 0
    if max_lowPress(leftLow, rightLow)[0] > max_lowPress(leftLow, rightLow)[1]:
        i += 1
    if average_press(leftHigh, leftLow, rightHigh, rightLow)[0] > \
            average_press(leftHigh, leftLow, rightHigh, rightLow)[1]:
        i += 1
    if average_highPress(leftHigh, rightHigh)[0] > average_highPress(leftHigh, rightHigh)[1]:
        i += 1
    if average_lowPress(leftLow, rightLow)[0] > average_lowPress(leftLow, rightLow)[1]:
        i += 1
    if average_differPress(leftHigh, leftLow, rightHigh, rightLow)[0] > \
            average_differPress(leftHigh, leftLow, rightHigh, rightLow)[1]:
        i += 1
    if i / 5 > 0.5:
        return "结论:左臂血压偏高"
    elif i / 5 == 0.5:
        return "结论:左臂血压与右臂血压相当"
    else:
        return "结论:右臂血压偏高"


# 格式输出一张表
def print_table(leftHigh1, leftLow1, rightHigh1, rightLow1, heart1):
    print(f"{'项目':<10}{'左臂'}{'右臂'.center(10, ' ')}")
    print(
        f"{'低压最高值':<8}{max_lowPress(leftLow1, rightLow1)[0]:.1f}{'':<6}{max_lowPress(leftLow1, rightLow1)[1]:.1f}")
    print(
        f"{'血压平均值':<8}{average_press(leftHigh1, leftLow1, rightHigh1, rightLow1)[0]:.1f}{'':<5}{average_press(leftHigh1, leftLow1, rightHigh1, rightLow1)[1]:.1f}")
    print(
        f"{'高压平均值':<8}{average_highPress(leftHigh1, rightHigh1)[0]:.1f}{'':<5}{average_highPress(leftHigh1, rightHigh1)[1]:.1f}")
    print(
        f"{'低压平均值':<8}{average_lowPress(leftLow1, rightLow1)[0]:.1f}{'':<6}{average_lowPress(leftLow1, rightLow1)[1]:.1f}")
    print(
        f"{'压差平均值':<8}{average_differPress(leftHigh1, leftLow1, rightHigh1, rightLow1)[0]:.1f}{'':<6}{average_differPress(leftHigh1, leftLow1, rightHigh1, rightLow1)[1]:.1f}")
    print(judge_press(leftHigh1, leftLow1, rightHigh1, rightLow1))
    print(f"{'心率平均值':<8}{average_heartRate(heart1):.1f}")


print_table(leftHigh, leftLow, rightHigh, rightLow, heart)

运行结果截图:
图片描述

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

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

题目思路:用3个列表来存储数据,逐行读取文件,然后利用split去进行分割分别存储到列表中,之后利用列表来计算即可。

程序代码:

"""
程序名:实验7.3.py
功能:假设当前目录下有一个文件名为class_score.txt的文本文件,
存放着某班学生的学号(第1列)、语文成绩(第2列)和数学成绩(第3列),以空格分割各列数据。
请编写程序完成下列要求:
(1)分别求出这个班语文成绩和数学成绩的平均分(保留1位小数)并输出。
(2)找出这个班两门课都不及格(<60)的学生,输出这些学生的学号、语文成绩和数学成绩。
(3)找出这个班两门课的平均成绩为优秀(≥90分)的学生,输出这些学生的学号、语文成绩、数学成绩和平均成绩。
日期:2022.5.21
版本:1.0
"""
# 读取成绩单
with open('class_score.txt') as fp:
    number, chinese, math = [], [], []
    i = 0
    for line in fp:
        a = line.strip().split(' ')
        number.append(a[0])
        chinese.append(int(a[1]))
        math.append(int(a[2]))
        i += 1


# 求语文成绩和数学成绩平均分
def average(chinese1, math1):
    average1 = sum(chinese1) / len(chinese1)
    average2 = sum(math1) / len(math1)
    print(f"全班语文成绩的平均分为:{average1:.1f},数学成绩的平均分为:{average2:.1f}")


# 求不及格的学生信息
def fail(number1, chinese1, math1):
    print("两门课都不及格的学生信息如下:")
    for i in range(len(number1)):
        if chinese1[i] < 60 and math1[i] < 60:
            print(number1[i], chinese1[i], end=' ')
            print(math1[i])


# 求优秀学生信息
def perfect(number1, chinese1, math1):
    print("两门课成绩的平均分在90分以上的学生信息如下:")
    for i in range(len(number1)):
        if (chinese1[i] + math1[i]) / 2 >= 90:
            print(number1[i], chinese1[i], math1[i], end=' ')
            print(f"{(chinese1[i] + math1[i]) / 2:.1f}")


average(chinese, math)
fail(number, chinese, math)
perfect(number, chinese, math)

运行结果截图:
图片描述
图片描述

4.编写程序,打开任意的文本文件,在指定的位置产生一个相同文件的副本,即实现文件的拷贝功能。
题目思路:利用shuffle库中的copy函数即可。
程序代码:

"""
程序名:实验7.4.py
功能:编写程序,打开任意的文本文件,在指定的位置产生一个相同文件的副本,即实现文件的拷贝功能。
日期:2022.5.21
版本:1.0
"""

import os
import shutil


def copyFile(Initpath, Newpath):  # 复制函数
    if not os.path.isfile(Initpath):
        print("文件不存在")
    else:
        path, name = os.path.split(Initpath)  # 分离文件名和路径
        if not os.path.exists(Newpath):
            os.makedirs(Newpath)  # 创建路径
        shutil.copy(Initpath, Newpath + name)  # 复制文件
        print(f"已经将{name}复制到{Newpath}目录下")


Initpath1 = input("请输入你要复制的文件:")
Newpath1 = input("请输入目标路径:")
copyFile(Initpath1, Newpath1)  # 复制文件
# 测试用:Initpath ='C:\Users\Lenovo\Desktop\python实验\实验7\class_score.txt'
# 测试用:Newpath = 'C:\Users\Lenovo\Desktop\python实验\新建文件夹\'

运行结果截图:
图片描述
图片描述
图片描述

5.在自己电脑任一盘符中新建以OS_Test命名的文件夹,并在该文件夹中新建以.doc .bmp .txt .png .jpeg .xlsx为扩展名的文件若干,请写一个程序,删除掉OS_Test目录里面(不包含子目录)所有的扩展名为.txt的文件,并将删除掉的文件名称打印出来。
题目思路:去遍历OS_Test中的文件,每次遍历都提取扩展名,如果扩展名为txt,则删除这个文件并打印。
程序代码:

"""
程序名:实验7.5.py
功能:在自己电脑任一盘符中新建以OS_Test命名的文件夹,并在该文件夹中新建以.doc .bmp .txt .png .jpeg .xlsx为扩展名的文件若干
请写一个程序,删除掉OS_Test目录里面(不包含子目录)所有的扩展名为.txt的文件,并将删除掉的文件名称打印出来。
日期:2022.5.21
版本:1.0
"""
import os


def delete_file(filepath, extenName):
    files = os.listdir(filepath)
    for file in files:
        if '.' in file:
            extenName2 = file.split('.')[1]  # 获取当前访问文件扩展名
            if extenName2 == extenName:  # 判断是否和要删除的文件扩展名相同
                os.remove(os.path.join(filepath, file))  # 相同即删除
                print(file + "已删除")


filepath1 = input("请输入要删除文件的目录:")
extenName1 = input("请输入要删除的文件的后缀:")
delete_file(filepath1, extenName1)
# 测试 filepath1 = 'D:\OS_Test'

运行结果截图:
图片描述
图片描述
图片描述

五、实验小结

问题与解决方法:

  1. 不知道f前缀的格式化输出如何保留小数位数。
    解决方法:通过上网查询得知,在f前缀中只要{变量:.xf}即可保留x位小数。
  2. 在输出血压表格的时候,发现不管怎么样,中文和数字都无法对齐。
    解决方法:在python中,英文和数字是半角字符,在输出和显示的时候只占1位字符,而中文是全角字符,输出和显示的时候占2位字符。而格式化输出的空格一般只占1位,所以有中文的时候很难对齐。
  3. 在自己读取的文件中,按行读取一直会读取到每行末尾的一个换行符,因此不能直接用空格来分割。
    解决方法:使用strip()来移除字符串头尾指定的字符(默认为空格或换行符)或字符序列,因此可以将末尾的换行符去掉然后就可以使用split正常分割了。
  4. 不知道如何去获取文件扩展名
    解决方法:可以直接将文件名以“.”来进行分割,这样可以避免用/来进行分割,分割出一大堆地址,用“.”的话,会把地址分为两部分,第二部分即为扩展名。

心得体会:

  1. python的文件操作十分强大,python给我们提供了好几个对文件进行操作的库,使用这些库可以让我们更加方便的去对文件进行操作。对于我们平时对电脑的使用也有很大帮助,学会这章内容以后,便可以自己去编写一些操作文件的程序,可以让我们在平时整理文件的时候更加高效快捷。
  2. 越往后学越感觉对于python的能力的认识越来越深,体会到了python本身虽然前面的基础内容学习十分简单快乐,但是学到后面的时候,发现自己对于书本上的例题感觉越来越难以掌握,这就要求我去更加深刻的学习书本上的例题代码,从而举一反三解决很多题目。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

我是一只大狸子

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

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

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

打赏作者

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

抵扣说明:

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

余额充值