Python第三周习题集(一) (工资结算系统 抽象类 静态方法 贪吃蛇 分数的重写 五子棋 大球吃小球 )


# 工资结算系统 1. 部门经理 1.5万元/月  2. 程序员 工作时间  150元/小时  3.销售员 1200底薪,+ %5销售额的提成
# 给你员工,得出工资。  员工类,父类  下面3类子类。
#我写的
class Staff(object): def __init__(self, name, age): self._name = name self._age = age @property def name(self): return self._name @property def age(self): return self._age class Department_manager(Staff): def __init__(self, name, age, salary): super().__init__(name, age) self._salary = salary @property def salary(self): return self._salary def get_money(self): print('%s岁的%s工作了一个月挣了%s' % (self._age, self._name, self._salary)) class Programer(Staff): def __init__(self, name, age, salary): super().__init__(name, age) self._salary = salary @property def salary(self): return self._salary def get_money(self, time): print('%s岁的%s工作了一个月共%s小时挣了%s' % (self._age, self._name, time, self._salary * time)) class Salesman(Staff): def __init__(self, name, age, sale): super().__init__(name, age) self._sale = sale @property def salary(self): return self._sale def get_money(self): salary = self._sale * 5 / 100 + 1200 print('销售员%s一个月挣了%s' % (self._name, salary)) def main(): which = str(input('请输入员工类型:部门经理/程序员/销售员')) if which == '部门经理': name = input('请输入名字') age = input('请输入年龄') man1 = Department_manager(name, age, '1.5万元') print(man1.get_money()) elif which == '程序员': name = input('请输入名字') age = input('请输入年龄') man2 = Programer(name, age, 150) time = int(input('请输入工作了多少小时')) print(man2.get_money(time)) elif which == '销售员': name = input('请输入名字') age = input('请输入年龄') sale = int(input('请输入销售额')) man3 = Salesman(name, age, sale) print(man3.get_money()) if __name__ == '__main__': main()

 抽象类

  Python没有从语言层面支持抽象类的概念,我们可以从abc模块来制造抽象类的效果。

  在定义类的时候,通过指定metaclass=ABCMeta可以将类声明为抽象类

  抽象类是不能创建对象的,抽象类只是拿来被继承的,给其他类继承

  abc模块中还有一个叫abstractmethon,通过这个包装器,可以将方法包装为抽象方法,必须要求子类重写。

rom abc import ABCMeta, abstractmethod


class Employee(object, metaclass=ABCMeta):
    """员工"""

    def __init__(self, name, age):
        """初始化方法"""
        self._name = name
        self._age = age

    @property
    def name(self):
        return self._name

    @property
    def age(self):
        return self._age

    @abstractmethod  # 变型为抽象类,以下的子类继承这个的时候,必须重写这个方法。
    def get_salary(self):
        """计算月薪"""
        pass


class Manager(Employee):

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

    def get_salary(self):
        return 15000


class Programer(Employee):

    def __init__(self, name, age):
        super().__init__(name, age)
        self._working_hour = 0

    @property
    def working_hour(self):
        return self._working_hour

    # 非必要属性,通过setter方法给出,必要属性,通过属性给出,不轻易修改
    @working_hour.setter
    def working_hour(self, working_hour):
        self._working_hour = working_hour if working_hour > 0 else 0

    def get_salary(self):
        return self._working_hour * 150


class Salesman(Employee):

    def __init__(self, name, age):
        super().__init__(name, age)
        self._sales = 0

    @property
    def sales(self):
        return self._sales

    @sales.setter
    def sales(self, sales):
        self._sales = sales if sales > 0 else 0

    def get_salary(self):
        return 1200 + self._sales * 5 / 100


def main():
    emps = [
        Manager('曹宇', 22), Programer('杨茜然', 22),
        Manager('张超', 22), Programer('李西北', 22),
        Salesman('刘家咯', 22)
    ]
    for emp in emps:
        # 识别类型,很重要*******
        if isinstance(emp, Programer):
            emp.working_hour = int(input('请输入%s本月工作时间:' % emp.name))
        elif isinstance(emp, Salesman):
            emp.sales = int(input('请输入%s本月销售额:' % emp.name))
        # 同样是接受get_salary这个消息,但是不用员工表现出了不同行为
        # 因为三个子类都重写了这个方法,所以这个方法会表现出多态行为
        print('%s本月工资为:¥%.2f元' % (emp.name, emp.get_salary()))


if __name__ == '__main__':
    main()

静态方法

  是用来发给这个类的爸爸的,不是发给这个类的。有两种方法。

  1.@staticmethon

  2.@classmethon 下面这个比上面这个多了一个参数,(cls)

from math import sqrt


class Triangle(object):

    def __init__(self, a, b, c):
        self._a = a
        self._b = b
        self._c = c

    # 静态方法, 用以发给类,不是发给对象的。就是发给它爸爸的。
    # @staticmethod   # @classmethod  也是发给类的,区别,
    # def is_valid(a, b, c):
    #     return a + b > c and a + c > b and b + c > a

    @classmethod  # @classmethod  也是发给类的,区别,
    def is_valid(cls, a, b, c):
        return a + b > c and a + c > b and b + c > a

    @property
    def perimeter(self):
        return self._a + self._b + self._c

    @property
    def area(self):
        half = self.perimeter / 2
        return sqrt(half * (half - self._a) * (half - self._b) * (half - self._c))


def main():
    a = b = c = 1
    if Triangle.is_valid(a, b, c):  # 静态方法。
        t = Triangle(a, b, c)
        print(t.perimeter)  # 对象来执行
        # 或者用 (Triangle.perimeter(t))  类来执行,传入参数。
        print(t.area)
    else:
        print('无法构成三角形!')


if __name__ == '__main__':
    main()

 贪吃蛇

import pygame
from random import randint
from abc import ABCMeta, abstractmethod

BLACK_COLOR = (0, 0, 0)
FOOD_COLOR = (236, 111, 187)
GREEN_COLOR = (0, 255, 0)

UP = 0
RIGHT = 1
DOWN = 2
LEFT = 3


class GameObject(object, metaclass=ABCMeta):

    def __init__(self, x=0, y=0, color=BLACK_COLOR):
        self._x = x
        self._y = y
        self._color = color

    @property
    def x(self):
        return self._x

    @property
    def y(self):
        return self._y

    @property
    def color(self):
        return self._color

    @abstractmethod  # 后面继承的子类都必须重写此方法,不然报错
    def draw(self, screen):
        pass


class SnakeNode(GameObject):  # 蛇节

    def __init__(self, x, y, size, color=GREEN_COLOR):
        """
        x y 为坐标,size为宽高。
        :param x:
        :param y:
        :param size:
        :param color:
        """
        super(SnakeNode, self).__init__(x, y, color)
        self._size = size

    @property
    def size(self):
        return self._size

    def draw(self, screen):
        """
        画蛇的节点,其中,位置,由左上的位置坐标和宽高组成。0,表示实心。
        :param screen:
        :return:
        """
        pygame.draw.rect(screen, self._color, [self._x, self._y, self._size, self._size], 0)
        pygame.draw.rect(screen, BLACK_COLOR, [self._x, self._y, self._size, self._size], 1)


class Snake(GameObject):

    def __init__(self):
        """由蛇节组成🐍"""
        super(Snake, self).__init__()
        self._dir = LEFT
        self._nodes = []
        self._alive = True
        for index in range(5):
            node = SnakeNode(290 + index * 20, 250, 20)
            self._nodes.append(node)

    @property
    def head(self):
        return self._nodes[0]

    @property
    def dir(self):
        return self._dir

    @property
    def alive(self):
        return self._alive

    def collide(self, wall):
        """撞到墙返回真,否则返回False"""
        head = self.head
        if head.x < wall.x or head.x + head.size > wall.x + wall.width\
            or head.y < wall.y or head.y + head.size > wall.y + wall.height:
            self._alive = False

    def eat_food(self, food):
        if self.head.x == food.x and self.head.y == food.y:
            tail = self._nodes[-1]
            self._nodes.append(tail)
            return True
        return False

    def draw(self, screen):
        for node in self._nodes:
            node.draw(screen)

    def move(self):
        if self._alive:
            snake_dir = self._dir
            x, y, size = self.head.x, self.head.y, self.head.size
            if snake_dir == UP:
                y -= size
            elif snake_dir == RIGHT:
                x += size
            elif snake_dir == DOWN:
                y += size
            else:
                x -= size
            new_head = SnakeNode(x, y, size)
            self._nodes.insert(0, new_head)
            self._nodes.pop()

    def change_dir(self, new_dir):
        if (self._dir + new_dir) % 2 != 0:
            self._dir = new_dir


class Wall(GameObject):

    def __init__(self, x, y, width, height, color=BLACK_COLOR):
        super(Wall, self).__init__(x, y, color)
        self._width = width
        self._height = height

    @property
    def width(self):
        return self._width

    @property
    def height(self):
        return self._height

    def draw(self, screen):
        pygame.draw.rect(screen, self._color, [self._x, self._y, self._width, self._height], 5)


class Food(GameObject):

    def __init__(self, x, y, size, color=FOOD_COLOR):
        super(Food, self).__init__(x, y, color)
        self._size = size
        self._hidden = False

    def draw(self, screen):
        """让食物闪烁起来"""
        if not self._hidden:
            pygame.draw.circle(screen, self._color,
                               (self._x + self._size // 2, self._y + self._size // 2),
                               self._size // 2, 0)
        self._hidden = not self._hidden


def main():
    def refresh():
        """刷新游戏窗口"""
        screen.fill([242, 242, 242])
        snake.draw(screen)
        wall.draw(screen)
        food.draw(screen)
        pygame.display.flip()

    def handle_key_event(key_event):
        """接受按键事件"""
        key = key_event.key
        if key == pygame.K_F2:
            reset_game()
        else:
            if snake.alive:
                new_dir = snake.dir
                if key == pygame.K_w:
                    new_dir = UP
                elif key == pygame.K_d:
                    new_dir = RIGHT
                elif key == pygame.K_s:
                    new_dir = DOWN
                elif key == pygame.K_a:
                    new_dir = LEFT
                if new_dir != snake.dir:
                    snake.change_dir(new_dir)

    def create_food():
        row = randint(0, 29)
        col = randint(0, 29)
        return Food(10 + 20 * row, 10 + 20 * col, 20)

    def reset_game():
        nonlocal food, snake
        food = create_food()
        snake = Snake()

    wall = Wall(10, 10, 600, 600)
    food = create_food()
    snake = Snake()
    pygame.init()
    pygame.display.set_caption('贪吃蛇')
    screen = pygame.display.set_mode([620, 620])  # 左上角是坐标原点。
    screen.fill([242, 242, 242])
    pygame.display.flip()
    clock = pygame.time.Clock()  # 帧数,游戏每秒的刷新次数。帧数越高越好,但是要机器能跟上。
    running = True
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            elif event.type == pygame.KEYDOWN:
                handle_key_event(event)  # 调用按键函数
        if snake.alive:
            refresh()  # 调用刷新函数
        clock.tick(10)  # 刷新次数
        if snake.alive:
            snake.move()
            snake.collide(wall)
            if snake.eat_food(food):
                food = create_food()
    pygame.quit()


if __name__ == '__main__':
    main()

分子分母的重写

from math import gcd


class Fraction(object):

    def __init__(self, num=1, den=1):  # 后面跟两个下划线,是共有的,如果后面有一个或没有,才是私有的。
        """
        分子分母
        :param num:分子
        :param den: 分母
        """
        if den == 0:
            raise ValueError('分母不能为零')  # 你敢让他为零,我就死给你看
        self._num = num
        self._den = den
        self.normalize()  # 自动调用正常化
        self.simplify()   # 自动调用化简

    @property
    def num(self):
        return self._num

    # @num.setter
    # def num(self, num):
    #     self._num = num

    @property
    def den(self):
        return self._den

    # @den.setter
    # def den(self, den):
    #     self._den = den

    def add(self, other):
        """加法"""
        return Fraction(self._num * other.den + self._den * other.num,
                        self._den * other.den)

    def __add__(self, other):
        """运算符重载/重写"""
        return self.add(other)

    def sub(self, other):
        """减法"""
        return Fraction(self._num * other.den - self._den * other.num,
                        self._den * other.den)

    def __sub__(self, other):
        return self.sub(other)

    def mul(self, other):
        """乘法"""
        return Fraction(self._num * other.num ,
                        self._den * other.den)

    def __mul__(self, other):
        return self.mul(other)

    def truediv(self, other):
        """除法"""
        return Fraction(self._num * other.den ,
                        self._den * other.num)

    def __truediv__(self, other):
        return self.truediv(other)

    def simplify(self):
        """
        化简
        :return:
        """
        if self._num != 0 and self._den != 1:
            factor = gcd(abs(self._num), abs(self._den))
            if factor > 1:
                self._den //= factor
                self._num //= factor

    def normalize(self):
        """
        正规化
        :return:
        """
        if self._den < 0:
            self._num = -self._num
            self._den = -self._den

    def __str__(self):
        """方法的自动调用"""
        if self._num == 0:
            return '0'
        elif self._den == 1:
            return str(self._num)
        else:
            return '%d/%d' % (self._num, self._den)


def main():
    f1 = Fraction(-1, -3)
    f2 = Fraction(4, 2)
    f3 = Fraction(0, 4)
    print(f1 + f2)
    print(f2 - f1)
    print(f3 * f1)
    print(f1 / f2)


if __name__ == '__main__':
    main()

五子棋

import pygame

EMPTY = 0
BLACK = 1
WHITE = 2

black_color = [0, 0, 0]
white_color = [255, 255, 255]


class RenjuBoard(object):

    def __init__(self):
        self._board = [[]] * 15
        self.reset()

    def reset(self):
        """重置棋盘"""
        for row in range(len(self._board)):
            self._board[row] = [EMPTY] * 15

    def move(self, row, col, is_black):
        if self._board[row][col] == EMPTY:
            self._board[row][col] = BLACK if is_black else WHITE
            return True
        return False

    def draw(self, screen):
        """
        画棋盘,天元,四点,画棋子
        :param screen:
        :return:
        """
        for i in range(1, 16):
            pygame.draw.line(screen, black_color, [40, i * 40], [600, i * 40], 1)  # 画行
            pygame.draw.line(screen, black_color, [i * 40, 40], [i * 40, 600], 1)  # 画列
        pygame.draw.rect(screen, black_color, [36, 36, 568, 568], 4)  # 画边框
        pygame.draw.circle(screen, black_color, [320, 320], 5, 0)  # 坐标,半径,0是实心,1是圆周的粗细
        pygame.draw.circle(screen, black_color, [160, 160], 5, 0)
        pygame.draw.circle(screen, black_color, [480, 480], 5, 0)
        pygame.draw.circle(screen, black_color, [160, 480], 5, 0)
        pygame.draw.circle(screen, black_color, [480, 160], 5, 0)
        for row in range(len(self._board)):
            for col in range(len(self._board[row])):
                if self._board[row][col] != EMPTY:  # 对于棋盘上的所有点,如果部位
                    ccolor = black_color if self._board[row][col] == BLACK else white_color
                    pos = [40 * (col + 1), 40 * (row + 1)]
                    pygame.draw.circle(screen, ccolor, pos, 18, 0)


def main():
    board = RenjuBoard()
    is_black = True
    pygame.init()
    pygame.display.set_caption('五子棋')
    screen = pygame.display.set_mode([640, 640])
    screen.fill([255, 255, 0])  # 红绿蓝三原色的值!
    board.draw(screen)
    pygame.display.flip()
    running = True
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            elif event.type == pygame.KEYUP:
                board.reset()
            elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
                x, y = event.pos
                row = round((y - 40) / 40)
                col = round((x - 40) / 40)
                if board.move(row, col, is_black):
                    is_black = not is_black
                    screen.fill([255, 255, 0])
                    board.draw(screen)
                    pygame.display.flip()
    pygame.quit()


if __name__ == '__main__':
    main()

打球吃小球

from random import randint
import pygame


class Ball(object):

    def __init__(self, center, color, radius, sx, sy):
        self._center = center
        self._color = color
        self._radius = radius
        self._sx = sx
        self._sy = sy

    @property
    def center(self):
        return self._center

    @property
    def radius(self):
        return self._radius

    def move(self):
        """移动后的坐标"""
        x, y = self._center[0], self._center[1]
        x += self._sx
        y += self._sy
        self._center = (x, y)
        if (x + self._radius >= 800 and self._sx > 0) or (x - self._radius <= 0 and self._sx < 0):
            self._sx = -self._sx
        if (y + self._radius >= 600 and self._sy > 0) or (y - self._radius <= 0 and self._sy < 0):
            self._sy = - self._sy

    def eat(self, other):
        pass

    def draw(self, screen):
        """画一个圆"""
        pygame.draw.circle(screen, self._color, self._center,
                           self._radius, 0)


def refresh(screen, balls):
    bg_color = (242, 242, 242)
    screen.fill(bg_color)
    for ball in balls:
        ball.draw(screen)
    pygame.display.flip()


def random_color():
    red = randint(0, 255)
    green = randint(0, 255)
    blue = randint(0, 255)
    return red, green, blue


def main():
    pygame.init()
    balls = []
    screen = pygame.display.set_mode([800, 600])  # 窗口大小
    pygame.display.set_caption('大球吃小球')  # 标题
    clock = pygame.time.Clock()
    running = True
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            elif event.type == pygame.MOUSEBUTTONDOWN and \
                    event.button == 1:
                # = event.pos
                color = random_color()
                radius = randint(10, 100)
                sx, sy = randint(-10, 10), randint(-10, 10)
                ball = Ball(event.pos, color, radius, sx, sy)
                balls.append(ball)
        refresh(screen, balls)
        clock.tick(20)
        for ball in balls:
            ball.move()
    pygame.quit()


if __name__ == '__main__':
    main()

 

posted @ 2018-03-17 10:40  摇还是不摇  阅读(356)  评论(0编辑  收藏  举报