【Python实验设计】自定义三维向量 / 学生教师显示类 / 公司职员类 / 球圆柱圆锥体积表面积计算 / 批量姓名住址随机信息 / 文本添加行 / 查找磁盘大小相同文件

 

目录

一、【自定义类模拟三维向量及其运算】

二、【编写一个学生和教师数据输入和显示程序】

三、【为一个公司编写职员数据类】

四、【编写一个程序计算出球、圆柱和圆锥的表面积和体积】

五、【批量生成姓名、家庭住址、电子邮箱等随机信息】

六、【读写文本文件并添加行号】

七、【查找磁盘内大小相同的文件】


一、【自定义类模拟三维向量及其运算】

       定义一个三位向量类My_3D,这个类有三个属性即是x,y,z,需要在类里面定义函数__add__和__sub__和__mul__以及show函数,这样分别实现加减乘法,实例化类后,就可以模拟三位向量及其运算。结合所学的数学知识利用Python编写对应函数。

# 自定义类模拟三维向量及其运算,加法、减法、向量与标量的乘法和除法


class My_3D(object):
    def __init__(self, x, y, z):
        self.a = x
        self.b = y
        self.c = z

    def __add__(self, other):
        my_add = My_3D(self.a + other.a, self.b + other.b, self.c + other.c)
        return my_add

    def __sub__(self, other):
        my_sub = My_3D(self.a - other.a, self.b - other.b, self.c - other.c)
        return my_sub

    def __mul__(self, other):
        my_mul = My_3D(self.a * other.a, self.b * other.b, self.c * other.c)
        return my_mul

    def show(self):
        print((self.a, self.b, self.c))


v1 = My_3D(1, 2, 3)
v2 = My_3D(4, 5, 6)
v_sum = v1 + v2
v_sub = v1 - v2
v_mul = v1 * v2

# 输出
print('原来的v1:')
v1.show()
print('原来的v2:')
v2.show()
print('相加得:')
v_sum.show()
print('相减得:')
v_sub.show()
print('相乘得:')
v_mul.show()

       测试实例化输入第一个三维向量(1,2,3)第二个三维向量(4,5,6),相加得(5,7,9)相减得(-3,-3,-3),相乘得(4,10,18),经测试实验结果符合预期,实验正确。

二、【编写一个学生和教师数据输入和显示程序】

学生数据有编号、姓名、班级和成绩

教师数据有编号、姓名、职称和部门

要求将编号、姓名输入和显示设计成一个类person;

设计类person的派生类:学生类student和教师类teacher;

       这主要是定义一个父类person,然后编写子类的时候,继承父类,其中很重要的函数:super().__init__()函数。在Python中, super() 是一个特殊的函数,用于调用父类的方法或属性。它经常与子类一起使用,以便在子类中扩展或重写父类的方法。

# 编写一个学生和教师数据输入和显示程序。其中,学生数据有编号、姓名和成绩,教师数据有编号、姓名、职称和部门。要求:
# 将编号、姓名输入和显示设计成一个类person
# 设计类person的派生类:学生类student和教师类teacher


class person(object):
    def __init__(self, num, name):
        self.num = num
        self.name = name

    def show(self):
        print(self.num, self.name)


class student(person):
    def __init__(self, num, name, cls, grades):
        super().__init__(num, name)    # 继承父类
        self.cls = cls
        self.grades = grades

    def show(self):
        print(self.num, self.name, self.cls, self.grades)


class teacher(person):
    def __init__(self, num, name, oppostion, location):
        super().__init__(num, name)    # 继承父类
        self.oppostion = oppostion
        self.location = location

    def show(self):
        print(self.num, self.name, self.oppostion, self.location)

# person1 = person(2021212981, '王忠全')
# person1.show()


student2 = student(2021212981, '王忠全', 8052102, 98,)
student2.show()

teacher3 = teacher(1013198974, '张老师', 'Python实验老师', '自动化学院')
teacher3.show()

测试实例化:

输入student,show展示学号,姓名,班级和成绩为:

2021212981 王忠全 8052102 98

输入teacher,show展示编号,姓名,职位和部门为:

1013198974 张老师 Python实验老师 自动化学院

经测试实验结果符合预期,实验正确。

三、【为一个公司编写职员数据类】

定义一个员工类Employee,有数据成员姓名,编号。

定义一个销售员继承自员工类Sales,工资为销售额的提成10%。

定义一个经理类Manager,固定工资8000。

定义一个销售经理类,继承自销售员类和经理类,工资为固定工资5000加销售额的提成5%。

每个类均有display函数输出信息,编写主函数测试。

这也主要是需要定义一个父类Employee,父类下有三个子类Sales、Manager、SalesManager,这三个子类都需要继承父类Employee,并且在每个子类都编写自己的money薪资函数以及展示show函数。

这里也利用super()函数继承了父类的Display展示函数。

# 定义一个员工类Employee,有数据成员姓名,编号。
# 定义一个销售员继承自员工类Sales,工资为销售额的提成10%
# 定义一个经理类Manager,固定工资8000
# 定义一个销售经理类,继承自销售员类以及经理类,工资为固定工资5000加销售额提成5%
# 每个类均有Display函数输出信息,编写主程序测试函数

# 员工类Employee
class Employee(object):
    def __init__(self, name, num):
        self.name = name
        self.num = num

    def Display(self):
        print('姓名:', self.name)
        print('编号:', self.num)


# 销售员类Sales
class Sales(Employee):
    def __init__(self, name, num, money):
        super().__init__(name, num)
        self.money = money

    def money_10per(self):
        money_10 = self.money * 0.1
        return money_10

    def Display(self):
        super(Sales, self).Display()
        print("销售员工资:", self.money_10per())


# 经理类Manager
class Manager(Employee):
    def __init__(self, name, num):
        super().__init__(name, num)

    def money_static(self):
        return 8000


    def Display(self):
        super(Manager, self).Display()
        print("经理工资:", self.money_static())


# 销售经理类SalesManager
class SalesManager(Sales, Manager):
    def __init__(self, name, number, money):
        Sales.__init__(self, name, number, money)
        Manager.__init__(self, name, number)

    def money_static_add(self):
        total_money = self.money * 0.05 + 5000
        return total_money

    def Display(self):
        super(SalesManager, self).Display()
        print("销售经理工资:", self.money_static_add())


print("----------")
xiaowang = Employee('小王', 2021212981)
xiaowang.Display()

print("----------")
xiaohu = Sales('小胡', 2021212989, 5400)
xiaohu.Display()

print("----------")
xiaonuo = Manager('小虎', 2020202964)
xiaonuo.Display()

print("----------")
xiaoguo = SalesManager('小狮', 2019264695, 7000)
xiaoguo.Display()

测试实例化,分别输入员工、销售员、经理、销售经理,得出:

----------

姓名: 小王

编号: 2021212981

----------

姓名: 小胡

编号: 2021212989

销售员工资: 540.0

----------

姓名: 小虎

编号: 2020202964

经理工资: 8000

----------

姓名: 小狮

编号: 2019264695

经理工资: 8000

销售员工资: 700.0

销售经理工资: 5350.0

经测试实验结果符合预期,实验正确。

四、【编写一个程序计算出球、圆柱和圆锥的表面积和体积】

定义一个基类,至少含有一个数据成员半径,并设为私有成员;

定义基类的派生类球、圆柱、圆锥,都含有求表面积和体积成员函数和打印函数;

编写主函数,求球、圆柱、圆锥的表面积和体积。

这里需要一个基类,我定义的就是半径数据成员,设置为私有成员,使用公有方法实现访问私有数据成员,即定义def public(self)返回值是self.__r私有的半径。

之后对于三个子类(球、圆柱、圆锥)继承父类,在子类中分定义函数求其对应的表面积和体积。

# 编写一个程序计算出球、圆柱和圆锥的表面积和体积,要求:
# 定义一个基类,至少含有一个数据成员半径,并设为私有成员;
# 定义基类的派生类球、圆柱、圆锥,都含有求表面积和体积的成员函数和打印函数;
# 编写主函数,求球、圆柱、圆锥的表面积和体积。
import math
pi = math.pi


class My_R(object):
    def __init__(self, r):
        self.__r = r

    def public_r(self):    # 公有方法访问私有r
        return self.__r


# 球
class My_Qiu(My_R):
    def __init__(self, r):
        super().__init__(r)
        self.r = self.public_r()

    def My_Qiu_V(self):
        return 4 / 3 * pi * pow(self.r, 3)

    def My_Qiu_S(self):
        return 4 * pi * pow(self.r, 2)

    def show(self):
        print("圆的半径:{0},体积:{1:.2f},表面积:{2:.2f}".format(self.r, self.My_Qiu_V(), self.My_Qiu_S()))


# 圆柱
class My_Yuanzhu(My_R):
    def __init__(self, r, h):
        super().__init__(r)
        self.r = self.public_r()
        self.h = h

    def My_Yuanzhu_V(self):
        return pi * pow(self.r, 2) * self.h

    def My_Yuanzhu_S(self):
        return 2 * pi * pow(self.r, 2) + 2 * pi * self.r * self.h

    def show(self):
        print("圆柱的半径:{0},体积:{1:.2f},表面积:{2:.2f}".format(self.r, self.My_Yuanzhu_V(), self.My_Yuanzhu_S()))


class My_Yuanzhui(My_R):
    def __init__(self, r, h, l):
        super().__init__(r)
        self.r = self.public_r()
        self.h = h
        self.l = l

    def My_Yuanzhui_V(self):
        return 1 / 3 * pi * pow(self.r, 2) * self.h

    def My_Yuanzhui_S(self):
        return pi * self.r * self.l + pi * pow(self.r, 2)

    def show(self):
        print("圆锥的半径:{0},体积:{1:.2f},表面积:{2:.2f}".format(self.r, self.My_Yuanzhui_V(), self.My_Yuanzhui_S()))

# 打印输入
Qiu1 = My_Qiu(2)
Qiu1.show()

Yuanzhu1 = My_Yuanzhu(2, 5)
Yuanzhu1.show()

Yuanzhi1 = My_Yuanzhui(2, 5, 8)
Yuanzhi1.show()

测试实例化:

输入球半径2;圆柱半径2,高5;圆锥半径2,高5,母线8

输出:

圆的半径:2,体积:33.51,表面积:50.27

圆柱的半径:2,体积:62.83,表面积:87.96

圆锥的半径:2,体积:20.94,表面积:62.83

经测试实验结果符合预期,实验正确。

五、【批量生成姓名、家庭住址、电子邮箱等随机信息】

并以二进制进行文件读写

生成:

对于批量生成随机信息数据,选取Python中的Faker包,它是开源的GITHUB项目,主要用来创建伪数据,使用Faker包,无需再手动生成或者手写随机数来生成数据,只需要调用Faker提供的方法,即可完成数据的生成。

所以利用Faker包获取随机的姓名、家庭地址、电子邮箱

name = fake.name()

address = fake.address()

email = fake.email()

写:

在这里,需要将随机信息转化成二进制文件,于是使用utf-8对随机信息进行编码,编码后还需要记录长度打包为二进制数据的一部分。主要是为了在读取数据时能够方便地找到每个字段的边界。因为在文件中,不同的字段可能会有不同的长度,如果没有一个明确的方式来标记每个字段的起始和结束位置,就很难准确地读取出每个字段的值。

通过在每个字段的前面添加一个表示其长度的 4 字节的无符号整数,就可以保证每个字段的长度都是固定的。在读取数据时,我们先读取 4 字节的长度信息,然后再根据长度信息读取对应长度的二进制数据,就能够准确地分割出每个字段的值。

这里使用struct库,重要的pack()函数对二进制数据进行打包。

读:

这里就是将之前打包的数据进行解码,读取指定长度的数据,按照utf-8解码为字符串,并且打印,就完成了读的操作。

# 批量生成姓名、家庭住址、电子邮箱等随机信息,并以二进制进行文件读 / 写。
# fake 库即可随机生成伪数据

import random
import faker
import struct

fake = faker.Faker()    # 实例化fake


# 随机生成:姓名、家庭住址、电子邮箱
def My_message():
    name = fake.name()
    address = fake.address().replace('\n', ', ')    # 把地址拼接到一段
    email = fake.email()
    return name, address, email  # 返回随机的姓名,地址,邮箱


# 批量生成随机信息写入二进制文件
def My_write(file_path, num_entries):
    with open(file_path, 'wb') as fp:
        for i in range(num_entries):    # 写入多少数量
            name, address, email = My_message()

            name_2data = name.encode('utf-8')    # 将字符串转换为二进制数据
            address_2data = address.encode('utf-8')
            email_2data = email.encode('utf-8')
            data = struct.pack('I', len(name_2data)) + name_2data     # 使用struct将数据打包为二进制格式
            data += struct.pack('I', len(address_2data)) + address_2data
            data += struct.pack('I', len(email_2data)) + email_2data
            fp.write(data)    # 写



# 从二进制文件中读取信息
def My_read(file_path):
    with open(file_path, 'rb') as fp:
        while True:
            length_data = fp.read(4)    # 从文件中读取4字节的数据,解析为字符串长度
            if not length_data:
                break
            length = struct.unpack('I', length_data)[0]
            data = fp.read(length)      # 读取指定长度的数据,并解码为字符串
            print(data.decode('utf-8')) # 打印


# 调用函数生成随机信息并写入二进制文件
file_path = 'My_file.bin'     # 写的文件名字
num_entries = 3                   # 随机生成信息的数量
My_write(file_path, num_entries)  # 写入文件
My_read(file_path)    # 从二进制文件中读取信息并打印

运行程序,可以看到终端输出了一系列随机的信息,并且将信息保存在文件“My_file”中,这样就实现了批量生成姓名、家庭住址、电子邮箱等随机信息,并以二进制进行文件读写。

经测试实验结果符合预期,实验正确。

六、【读写文本文件并添加行号】

这里就是需要读取一个文件,用readlines()函数读出每一行内容,并把读到的每一行的索引值和内容取出,这里考虑用enumerate()函数,然后遍历,对每一行进行写入,即可实现读取文本并添加行号。

# 读写文本文件并添加行号。

def My_Addline(file, file_change):
    with open(file, 'r', encoding='utf-8', errors='ignore') as fp:    # 以读模式打开文件
        lines = fp.readlines()    # 读取每一行
        print(lines)

    with open(file_change, 'w', encoding='utf-8') as fp_change:    # 以写模式打开文件
        # for i, line in enumerate(lines, 1):
        #     fp_change.write(f"{i}: {line}")
        for index, item in enumerate(lines):    # 获取行数与行内容
            print(index+1)    # 行数需要+1,不然是从第0行开始的
            print(item)
            fp_change.write("第{0}行:{1}".format(index+1, item))


file = "My_file_2.txt"  # 输入文件名
file_change = "My_file_change.txt"  # 输出文件名
My_Addline(file, file_change)

可以看到终端输出了数字和一行一行的信息,我们在文件中看看。

没有添加行号前My_file_2:

添加行号后My_file_change:

可以看到程序运行后,给txt文本每一行添加了行号,第一行、第二行……经测试实验结果符合预期,实验正确。

七、【查找磁盘内大小相同的文件】

这里主要是需要遍历文件目录,将文件的大小size和路径path存储在一个字典里面,按照键值对,如果文件大小相同,则size共用一个键,值path存在多个。

这样只需要寻找size键下路径path数大于2的,就找到了相同文件啦。

# 查找磁盘内大小相同的文件
# 遍历目录及其子目录中的所有文件,将它们的文件大小作为键,文件路径作为值存储在一个字典中。
# 如果多个文件具有相同的文件大小,则将路径添加到相应的列表中

import os


def My_find_file(fp):
    file_size = {}    # 定义一个文件大小字典

    for dirpath, dirnames, filenames in os.walk(fp):
        # os.walk() 函数
        # 第一个参数 dirpath:需要遍历的文件夹路径
        # 第二个参数 dirnames:当前文件夹下所有子文件夹的名称列表
        # 第三个参数 filenames:当前文件夹下所有文件的名称列表
        for filename in filenames:
            path = os.path.join(dirpath, filename)    # 拼接函数
            print(path)
            size = os.path.getsize(path)
            print("文件大小:", size)

            if size not in file_size:      # 按照文件大小存储文件路径
                file_size[size] = [path]   # 键是文件大小,值是文件路径
            else:
                file_size[size].append(path)    # 如果有相同文件大小,则直接存路径

    # 开始查找相同大小文件
    for size, paths in file_size.items():
        if len(paths) >= 2:     # 如果一个文件大小键下有两个路径值 -- 则重复
            print("\n发现具有相同大小的文件啦:")
            for path in paths:
                print(path)

    print("\n程序结束~")


My_path = "C:/Users/Akaxi/Desktop/Akaxi_python/Python_experiment_Akaxi/第三次实验"  # 替换为你所需的目录
My_find_file(My_path)

我在指定目录:C:/Users/Akaxi/Desktop/Akaxi_python/Python_experiment_Akaxi/第三次实验

创建了两相同大小的文件My_file_chongfu_1.txt和My_file_chongfu_2.txt,运行程序,输出结果找到了大小相同的文件,并且把目录也打印出来,根据我的目录结构,经测试实验结果符合预期,实验正确。

总结

       对于第一问:自定义类模拟三维向量及其运算,学会了Python中很重要的class类定义与求解,学会了__add__和__sub__和__mul__函数。

       对于第二问:编写一个学生和教师数据输入和显示程序,学会了定义一个父类,然后编写子类的时候,继承父类,学会了其中很重要的函数:super().__init__()函数。

       对于第三问:为一个公司编写职员数据类,这也主要是需要定义一个父类,父类下有三个子类,这三个子类都需要继承父类,并且在每个子类都编写自己的money薪资函数以及展示show函数。利用super()函数继承了父类的Display展示函数。

       对于第四问:编写一个程序计算出球、圆柱和圆锥的表面积和体积。学会了设置私有成员,使用公有方法实现访问私有数据成员,即定义def public(self)返回值是self.__r私有的半径。之后对于三个子类(球、圆柱、圆锥)继承父类,在子类中分定义函数求其对应的表面积和体积。

       对于第五问:批量生成姓名、家庭住址、电子邮箱等随机信息。学会了Faker包获取随机的姓名、家庭地址、电子邮箱。还学会了将随机信息转化成二进制文件,使用utf-8对随机信息进行编码,编码后还需要记录长度打包为二进制数据的一部分。学会了struct库,重要的pack()函数对二进制数据进行打包。也学会了unpack()对打包数据进行解包,读取指定长度的数据,按照utf-8解码为字符串,并且打印,完成了读的操作。

       对于第六问:读写文本文件并添加行号。学会了读取一个文件,用readlines()函数读出每一行内容,并把读到的每一行的索引值和内容取出,学会了用enumerate()函数,然后遍历,对每一行进行写入,即可实现读取文本并添加行号。

       对于第七问:查找磁盘内大小相同的文件。学会了遍历文件目录,将文件的大小size和路径path存储在一个字典里面,按照键值对,如果文件大小相同,则size共用一个键,值path存在多个。寻找size键下路径path数大于2的,就找到了相同文件。

2023.10.31

渝北仙桃数据谷

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Akaxi-1

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

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

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

打赏作者

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

抵扣说明:

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

余额充值