面向对象编程 - 练习

面向对象编程 - 练习

# 描述平面上的点,提供移动点,计算一个点到另一个点的方法
import math


class Dot:

    def __init__(self, x, y):
        """
        初始化方法
        :param x: 初始点x轴坐标
        :param y: 初始点y轴坐标
        """
        self.x = x
        self.y = y

    def move_to(self, x, y):
        """移动到某个点"""
        self.x = x
        self.y = y

    def move_by(self, length, width):
        """根据偏移量移动点"""
        return self.x + length, self.y + width

    def distance(self, other):
        """计算到某个点的距离"""
        return ((self.x - other.x) ** 2 + (self.y - other.y) ** 2) ** 0.5

    def __str__(self):
        return f'({self.x}, {self.y})'
# 描述平面上的线段,提供计算线段长度,判断一个线段与另一个线段是否相交


class LineSegment:

    # 复用定义的点类,创建线段就会很方便
    def __init__(self, start: Dot, end: Dot):
        """
        初始化方法
        :param start:线段起点
        :param end:线段终点
        """
        self.start = start
        self.end = end

    def length(self):
        """计算线段长度"""
        return self.start.distance(self.end)

    def is_intersect(self, other):
        """判断线段是否相交"""
        sx1, sy1, ex1, ey1 = self.start.x, self.start.y, self.end.x, self.end.y
        sx2, sy2, ex2, ey2 = other.start.x, other.start.y, other.end.x, other.end.y
        return not(
                max(sx1, ex1) < min(sx2, ex2) or
                max(sx2, ex2) < min(sx1, ex1) or
                max(sy1, ey1) < min(sy2, ey2) or
                max(sy2, ey2) < min(sy1, ey1)
        )
# 扑克游戏,对应的对象和属性和方法
"""
1. 牌 - 花色、点数 - 显示牌面、比大小
2. 扑克 - 装54张牌的列表 - 被洗牌、被发牌
3. 玩家 - ID、昵称、手牌(列表) - 摸牌、出牌、整理手牌
"""

# 符号常量总是优于字面常量!!! 将变量名大写,表示该变量是常量
# 优质的代码,总是很少使用字面常量
import random

SPADE, HEART, CLUB, DIAMOND = range(4) # 四种花色,分别用四个数字映射,同时方便排序

# 构建单张牌
class Card:
    """牌"""

    def __init__(self, suite, face):
        """
        初始化方法
        :param suite: 花色
        :param face: 点数
        """
        self.suite = suite
        self.face = face

    def __repr__(self):
        return self.show()

    def __lt__(self, other):  # 魔术方法,相当于<
        """
        牌面排序规则
        :param other:另一张牌
        :return:
        """
        if self.suite != other.suite:   # 花色相同直接放在一起
            return self.suite < other.suite
        face1 = 14 if self.face == 1 else self.face  # 将A放在最后,表示最大
        face2 = 14 if other.face == 1 else other.face
        return face1 < face2

    def show(self):
        """显示牌面"""
        suites = ('♠', '♥', '♣', '♦')
        faces = ('', 'A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'k')
        return f'{suites[self.suite]}{faces[self.face]}'


# 定义一个扑克类
class Poker:
    """扑克牌"""

    def __init__(self):
        """初始化方法"""
        self.cards = [Card(suite, face)
                      for suite in range(4)
                      for face in range(1, 14)]   # 循环获取花色和点数,创建一副扑克牌
        self.index = 0   # 索引标记每张牌的位置

    def shuffle(self):
        """洗牌"""
        self.index = 0
        random.shuffle(self.cards)   # 随机排序,Python中定义好的方法和自己创建的方法不会冲突

    def has_more(self):
        """判断是否还有剩余的牌"""
        return self.index < len(self.cards)

    def deal(self):
        """发牌"""
        card = self.cards[self.index]
        self.index += 1
        return card


class Player:
    """玩家"""

    def __init__(self, nickname):
        """
        初始化方法
        :param nickname: 玩家昵称
        """
        self.nickname = nickname
        self.cards = []   # 玩家手牌列表

    def get_card(self, card):
        """摸牌"""
        self.cards.append(card)

    def arrange(self):
        """整理手牌"""
        # self.cards.sort(key=lambda x: x.face)   # 列表的sort方法可以传入key
        self.cards.sort()


poker = Poker()
poker.shuffle()
names = ('妲己', '吕布', '赵云', '孙武')
players = [Player(name) for name in names]

for _ in range(13):
    for player in players:
        card = poker.deal()
        player.get_card(card)

for player in players:
    player.arrange()
    print(player.nickname, end=':')
    print(player.cards)
# 倒计时时钟
import time


class CountDownClock:

    def __init__(self, hour, minute, second):
        """
        初始化时间
        :param hour:时
        :param minute:分
        :param second: 秒
        """
        self.hour = hour
        self.minute = minute
        self.second = second

    def show(self):
        """显示"""
        return f'{self.hour:0>2d}:{self.minute:0>2d}:{self.second:0>2d}'

    def is_over(self):
        """判断倒计时计时器是否结束"""
        return self.hour == 0 and self.minute == 0 and self.second == 0

    def is_running(self):
        """判断倒计时计时器是否还在运行"""
        return self.hour != 0 or self.minute != 0 or self.second != 0

    def run(self):
        """走字"""
        if not self.is_over():
            self.second -= 1
            if self.second < 0:
                self.second = 59
                self.minute -= 1
                if self.minute < 0:
                    self.minute = 59
                    self.hour -= 1


clock = CountDownClock(1, 0, 1)
while not clock.is_over():
    print(clock.show())
    time.sleep(1)
    clock.run()
print('时间到!')
# 定义一个类,描述一个三角形


class Triangle:

    def __init__(self, a, b, c):
        """
        初始化方法
        :param a:第一条边
        :param b:第二条边
        :param c:第三条边
        """
        self.a = a
        self.b = b
        self.c = c

    @staticmethod    # 装饰器,定义一个静态方法,不是发给对象的消息,而是发给类的消息。与类方法相同,只是类方法比静态方法多一个参数,表示接收消息的类名
    def is_structure(a, b, c):
        return a + b > c and a + c > b and b + c > a

    @classmethod    # 类方法,与静态方法相同,只是类方法比静态方法多一个参数,表示接收消息的类名
    def is_valid_sides(cls, a, b, c):
        return a + b > c and a + c > b and b + c > a

    def perimeter(self):
        return self.a + self.b + self.c

    def area(self):
        p = self.perimeter() / 2
        a, b, c = self.a, self.b, self.c
        return math.sqrt(p * (p - a) * (p - b) * (p - c))


def main():
    # a, b, c = map(float, input('请输入三条边的长度:').split())
    a = float(input('输入第一条边的长度:'))
    b = float(input('输入第二条边的长度:'))
    c = float(input('输入第三条边的长度:'))
    if Triangle.is_structure(a, b, c):
        tri = Triangle(a, b, c)
        print(f'三角形的周长:{tri.perimeter()}')
        print(f'三角形的面积:{tri.area()}')
    else:
        print('不能构成三角形')


if __name__ == '__main__':
    main()
"""
工资结算系统
- 部门经理:15000元
- 程序员:计算工时 ---> 200元/小时 * 本月工时
- 销售员:底薪+提成 ---> 1800元 + 本月销售额的5%提成

给出员工的信息,自动结算月薪
"""


class Employee:
    """雇员"""

    def __init__(self, name, post):
        """
        初始化方法
        :param name: 姓名
        :param post: 部门
        """
        self.name = name
        self.post = post


class Manager(Employee):
    """部门经理"""

    def __init__(self, name, post):
        super().__init__(name, post)

    def salary(self):
        """月薪"""
        return '15000元'


class Programmer(Employee):
    """程序员"""

    def __init__(self, name, post, language):
        super().__init__(name, post)
        self.language = language

    def salary(self, hour):
        return f'{hour * 200}元'


class Salesman(Employee):
    """销售员"""

    def __init__(self, name, post):
        super().__init__(name, post)

    def salary(self, sales):
        """月薪"""
        return f'{sales * 0.05 + 1800}元'
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值