【Python】第四次实验

1

# 1. 编写一个学生类Student,定义3个属性name、age和id,分别表示学生的姓名、年龄和学号。第一个学生的学号为1,
# 以后每生成一个学生对象,学号增加1。初始化学生对象时,需要提供姓名和年龄。每个学生对象生成以后需要调用自定义的info()方法输出姓名、年龄和学号。

class Student:
    __curr_id = 1

    def __init__(self, name, age):
        self.id = Student.__curr_id
        Student.__curr_id += 1
        self.name = name
        self.age = age

    def info(self):
        print(f"姓名 {self.name}\t年龄 {self.age}\t学号 {self.id}")


s1 = Student("Danny", 18)
s1.info()
s2 = Student("Jerry", 19)
s2.info()
s3 = Student("Jenny", 17)
s3.info()

2

# 2. 创建类MyMath,计算圆的周长、面积和球的表面积、体积,结果保留两位小数。提示:要引入math包。例如,请输入半径:5
#         圆的周长:31.42
#         圆的面积:78.54
#         球的表面积:314.16
# 附加功能(可选):非法数值判断
# 若输入的是非数字,则输出:请输入数字!
# 若输入的是负数,则输出:请输入正数!
import math
class MyMath:
    def __init__(self):
        while True:
            self.r = input("请输入半径;")
            if self.r.startswith('-') and len(self.r) == 1:
                print("请输入数字!")
            elif not self.r.lstrip('-').isdigit():
                print("请输入数字!")
            elif float(self.r) < 0:
                print("请输入正数!")
            else:
                self.r = float(self.r)
                break

    def calculate(self):
        circle_c = 2 * math.pi * self.r
        circle_s = math.pi * self.r**2
        ball_s = 4 * math.pi * self.r**2
        ball_v = 4/3 * math.pi * self.r**3
        print(f"圆的周长:{circle_c:.2f}\n圆的面积:{circle_s:.2f}\n球的表面积;{ball_s:.2f}\n球的体积:{ball_v:.2f}")


m = MyMath()
m.calculate()

3

# 3. 实现一个名为“Rectangle”的表示矩形的类,该类包含两个实例属性width和height,分别表示矩形的宽和高,
# 都是可读写的property,并且在写操作时检查是否为正值。同时,还有一个名为area()的方法,是一个只读的property,该方法返回矩形的面积。

class Rectangle:
    def __init__(self, width, height):
        self._width = width
        self._height = height

    # 可读
    @property
    def width(self):
        return self._width

    # 可写
    @width.setter
    def width(self, value):
        if value > 0:
            self._width = value
        else:
            print("传入的值不是正数")

    # 可读
    @property
    def height(self):
        return self._height

    # 可写
    @height.setter
    def height(self, value):
        if value > 0:
            self._height = value
        else:
            print("传入的值不是正数")

    # 可读
    @property
    def area(self):
        return self._width * self._height


r1 = Rectangle(5, 10)
print("宽:", r1.width)
print("高:", r1.height)
print("面积:", r1.area)

r1.width = -8
r1.width = 8
r1.height = -12
r1.height = 12
print("新的宽:", r1.width)
print("新的高:", r1.height)
print("新的面积:", r1.area)

4

# 4. 自定义类模拟三维向量及其运算。包括向量的加法、减法以及向量与标量的乘法和除法,并查看向量长度。
# 例如,a=(x1,y1,z1), b=(x2,y2,z2)
#       a+b=(x1+x2,y1+y2,z1+z2), a-b=(x1-x2,y1-y2,z1-z2)
#       n=10, a*n=(x1*n,y1*n,z1*n), a/n=(x1/n,y1/n,z1/n)
#       a.length=(x1**2+y1**2+z1**2)**0.5
import math


class Vector_3D:
    # 构造方法
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z

    # 使用算术魔法方法定义加减乘除
    def __add__(self, other):
        return Vector_3D(self.x + other.x, self.y + other.y, self.z + other.z)

    def __sub__(self, other):
        return Vector_3D(self.x - other.x, self.y - other.y, self.z - other.z)

    def __mul__(self, s):
        return Vector_3D(self.x * s, self.y * s, self.z * s)

    def __truediv__(self, s):
        if s != 0:
            return Vector_3D(self.x / s, self.y / s, self.z / s)
        else:
            print("除数不能为0!")

    # 获取向量长度
    def length(self):
        return math.sqrt(self.x ** 2 + self.y ** 2 + self.z ** 2)


a = Vector_3D(1, 2, 3)
b = Vector_3D(4, 5, 6)

c = a + b
d = a - b
e = a * 10
f = a / 10

print(f"a+b=({c.x},{c.y},{c.z})")
print(f"a-b=({d.x},{d.y},{d.z})")
print(f"a*10=({e.x},{e.y},{e.z})")
print(f"a/10=({f.x},{f.y},{f.z})")

print("向量a的长度:", a.length())
print("向量b的长度:", b.length())
print("向量c的长度:", c.length())
print("向量d的长度:", d.length())
print("向量e的长度:", e.length())
print("向量f的长度:", f.length())

5

# 5.设计一个摆放家具实例,要求:
# (1)房子(House) 有户型、总面积和家具名称列表(新房子没有任何的家具);
# (2)家具(HouseItem)有名字和占地面积,其中席梦思(bed) 占地4平米、衣柜(chest)占地2平米、餐桌(table)占地1.5平米;
# (3)将以上三件家具添加到房子中;
# (4)打印房子时,要求输出:户型、总面积、剩余面积、家具名称列表。

class HouseItem:
    def __init__(self, name, area):
        self.name = name
        self.area = area


class House:
    def __init__(self, model, total_area):
        self.model = model
        self.total_area = total_area
        self.remaining_area = total_area
        self.item_list = []

    def add_item(self, item):
        # 检查家具占地面积是否超出剩余面积
        if item.area > self.remaining_area:
            print(f"错误:无法添加{item.name},超出剩余面积!")
            return
        self.item_list.append(item.name)
        self.remaining_area -= item.area

    def print_house(self):
        print(f"房子户型:{self.model}\n总面积:{self.total_area},剩余面积:{self.remaining_area}\n家具:{','.join(self.item_list)}")


# 创建家具实例
bed = HouseItem("席梦思", 4)
chest = HouseItem("衣柜", 2)
table = HouseItem("餐桌", 1.5)

# 创建房子实例
my_house = House("两室一厅", 60)

# 添加家具
my_house.add_item(bed)
my_house.add_item(chest)
my_house.add_item(table)

# 打印房子信息
my_house.print_house()

6

# 6. 继承 Python内置的字符串类str,根据给定整数(正数代表左移,负数代表右移)实现字符串的左右循环移动。
# 例如,a = MoveableStr("abcde")
#       print(a.move(3))  # 输出deabc
#       print(a.move(-3))  # 输出cdeab

class MoveableStr(str):
    def move(self, n):
        n %= len(self)  # 防止n大于字符串长度,取余数
        if n == 0:
            return self
        if n > 0:
            return self[n:] + self[:n]
        else:
            return self[n:] + self[:n]


a = MoveableStr("abcde")
print(a.move(3))  # 输出deabc
print(a.move(-3))  # 输出cdeab

7

# 7. 定义类Dimension(包含x、y坐标),类Circle和 Rectangle继承了Dimension的成员变量x和y,并重写继承的方法area()。

import math


class Dimension:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    # 父类不具体实现area方法,等子类重写
    def area(self):
        pass


class Circle(Dimension):
    def __init__(self, x, y, radius):
        # 调用父类的构造方法
        Dimension.__init__(self, x, y)
        self.radius = radius

    # 重写父类的area方法
    def area(self):
        return math.pi * self.radius ** 2


class Rectangle(Dimension):
    def __init__(self, x, y, width, height):
        # 调用父类的构造方法
        Dimension.__init__(self, x, y)
        self.width = width
        self.height = height

    # 重写父类的area方法
    def area(self):
        return self.width * self.height


circle = Circle(0, 0, 5)  # 圆心在(0,0),半径为5
rectangle = Rectangle(0, 0, 3, 4)  # 矩形左下角在(0,0),宽度为3,高度为4

print("圆的面积:", circle.area())  # 打印圆的面积
print("矩形的面积:", rectangle.area())  # 打印矩形的面积

8

# 8. 请定义类Point(一个点包含x、y坐标),通过重写相应的魔方方法,使其支持如下运算符操作:
# (1)p1+p2,两个点的x、y坐标分别相加,返回一个新的 Point对象;
# (2)p1-p2,两个点的x、y坐标分别相减,返回一个新的 Point对象;
# (3)p*n,用点的x、y坐标分别乘以数值n,返回一个新的Point对象;
# (4)p/n,用点的x、y坐标分别除以数值n,返回一个新的Point对象。

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    # 使用算术魔法方法定义加减乘除
    def __add__(self, other):
        return Point(self.x + other.x, self.y + other.y)

    def __sub__(self, other):
        return Point(self.x - other.x, self.y - other.y)

    def __mul__(self, n):
        return Point(self.x * n, self.y * n)

    def __truediv__(self, n):
        return Point(self.x / n, self.y / n)

    def __repr__(self):
        return f"Point({self.x}, {self.y})"


if __name__ == '__main__':
    a,b=Point(4,5),Point(2,3)
    print(a+b)  # 输出结果为'Point(6,8)'
    print(a-b)  # 输出结果为'Point(2,2)'
    print(a*2)  # 输出结果为'Point(8,10)'
    print(a/2)   # 输出结果为'Point(2.0,2.5)'

9

# 9. 创建SchoolMem类,该类中包含三个数据成员:姓名、性别、年龄;创建Student类,继承自SchoolMem类,添加额外三个数据成员:
# 班级、学号和数量统计;创建Teacher类,继承自SchoolMem类,添加额外三个数据成员:学院、工号和数量统计。
# 要求给每个类适当添加属性、成员方法和特殊方法(如构造方法),实现学生和教师信息的输出。实现并测试这个类。
# (建议在父类和子类中使用同名函数以实现多态,如在SchoolMem类、Student类和Teacher类中分别实现printInfo方法输出对象的信息。)

# SchoolMem 父类
class SchoolMem:
    # 类属性,累计SchoolMem的数量
    member_count = 0

    def __init__(self, name, gender, age):
        self.name = name
        self.gender = gender
        self.age = age
        SchoolMem.member_count += 1

    # 打印信息
    def printInfo(self):
        print(f"姓名:{self.name}, 性别:{self.gender}, 年龄:{self.age}")


# Student 子类
class Student(SchoolMem):
    student_count = 0  # 类变量,用于统计Student的数量

    def __init__(self, name, gender, age, class_name, student_id):
        super().__init__(name, gender, age)
        self.class_name = class_name
        self.student_id = student_id
        Student.student_count += 1

    # 打印信息,重写父类的方法
    def printInfo(self):
        SchoolMem.printInfo(self)
        print(f"班级:{self.class_name}, 学号:{self.student_id}")


# Teacher 子类
class Teacher(SchoolMem):
    teacher_count = 0  # 类变量,用于统计Teacher的数量

    def __init__(self, name, gender, age, college, staff_id):
        super().__init__(name, gender, age)
        self.college = college
        self.staff_id = staff_id
        Teacher.teacher_count += 1

    # 打印信息,重写父类的方法
    def printInfo(self):
        SchoolMem.printInfo(self)
        print(f"学院:{self.college}, 工号:{self.staff_id}")


# 创建学生和教师
student = Student("程序员", "男", 19, "23软工智能", "88888888")
teacher = Teacher("闫书记", "女", 40, "智能制造学院", "10086")

# 输出学生和教师的信息
student.printInfo()
teacher.printInfo()

# 输出学生和教师的总数
print(f"学生数量:{Student.student_count}")
print(f"教师数量:{Teacher.teacher_count}")

10

# 10. 设计一个车类,属性:车的类型、车的速度,分别再建立两个子类:小汽车类、电动汽车类去继承车类,为了实现汽车增加能源的方式,
# 在父类中添加一个增加能源方法increased_energy(),通过汽车对象不同分别实现小汽车类加 油、电动汽车充电的实现。

class Car:
    def __init__(self, car_type, speed):
        self.car_type = car_type
        self.speed = speed

    # 父类不具体实现,子类进行重写
    def increased_energy(self):
        pass


class LittleCar(Car):
    def increased_energy(self):
        print(f"{self.car_type}正在加油,当前速度为:{self.speed}km/h")


class ElectricCar(Car):
    def increased_energy(self):
        print(f"{self.car_type}正在充电,当前速度为:{self.speed}km/h")


little_car = LittleCar("小汽车", 120)
electric_car = ElectricCar("电动汽车", 100)

little_car.increased_energy()
electric_car.increased_energy()

实验总结

这10个实验都是Python面向对象中相对基础的内容,在第二个实验中判断非法数值时需要先判断字符串开头是否为"-"(符号),然后判断字符串长度是否为1,即只有一个负号,然后第二个判断是判断去掉符号只后是否为数字,因为isdigit()不能直接判断负数字符串,最后把字符串转换成float类型判断是否为负数,总之三个判断过程还是有点绕的。然后第4个和第8个实验主要是用到了魔法方法,这里的魔法方法属于算数魔法方法,类似于C++中的运算符重载,为此我查阅了相关资料整理成了笔记:https://notes.smallbamboo.cn/python-magic-method.html。其他实验没有什么问题。

© 版权声明
THE END
点赞13 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容