day18- 面向对象程序进阶和继承(10.13)
1、作业讲评-倒计时计时器
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_running(self):# 德莫方法
"""判断倒计时是否还在运行"""
return self.hour != 0 or self.minute != 0 or self.second != 0
# 方法二:反向书写
# def is_over(self):
# """判断倒计时是否结束(返回bool值)"""
# return self.hour == 0 and self.minute == 0 and self.second == 0
def run(self):
# if not self.is_over():
if self.is_running():
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(0, 1, 5)
print(clock.show())
# while not clock.is_over():
while clock.is_running():
time.sleep(1)
clock.run()
print(clock.show())
print('倒计时结束,时间到了')
2、练习
练习1:定义类描述平面上的点,提供移动点,计算一个点到另一个点距离的方法
练习2:定义类描述平面上的线段,提供计算线段长度,判断一个线段与另一个线段是否相交的方法
练习3:三角形,周长,面积
bi / do / du 二–> double
tri --> 三
quarter
penta
# 自己的练习1
import math
class Point:
def __init__(self, x1, y1, x2, y2):
self.x1 = x1
self.x2 = x2
self.y1 = y1
self.y2 = y2
def distance(self):
return ((self.x1-self.x2)**2+(self.y1-self.y2)**2)**0.5
point = Point(1, 2, 3, 4)
print(point.distance())
#teacher的答案练习1:
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def move_to(self, x, y): #直接移动到某一位置
self.x = x
self.y = y
def move_by(self, dx, dy): #移动偏移量
self.x += dx
self.y += dy
def distance(self, other):
return math.sqrt((self.x - other.x)**2+(self.y-other.y)**2) #????为什么这里可以传参数other
def __repr__(self):
# return f'({self.x},{self.y})'
return f'<{self.x},{self.y}>'
p1 = Point(3, 5)
p2 = Point(6, 1)
p1.move_to(1, -1)
p2.move_by(1, -1)
print(p1, p2)
print(p1.distance(p2))
p2.move_by(1, -1)
print(p1.distance(p2))
练习2:定义类描述平面上的线段,提供计算线段长度,判断一个线段与另一个线段是否相交的方法
**答案
class Line:
def __init__(self, start: Point, end: Point):
self.start = start
self.end = end
def length(self):
# 通过Point对象,调用distance方法,来计算线段的距离而不是重新写公式进行计算,这是对已有代码的复用
return self.start.distance(self.end) # 为什么可以继续使用上面的方法
def intersected(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, self.end.x, self.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))
p1 = Point(3, 5)
p2 = Point(6, 1)
p1.move_to(1, -1)
p2.move_by(1, -1)
print(p1, p2)
print(p1.distance(p2))
p2.move_by(1, -1)
print(p1.distance(p2))
line1 = Line(p1, p2)
print(line1.length())
p3 = Point(-1, -2)
p4 = Point(6, 2)
line2 = Line(p3, p4)
print(line2.length())
print(line2.intersected(line1))
p3.move_to(4, 5)
line3 = Line(p3, p4)
print(line1.intersected(line3))
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FyIE2IWl-1634122631640)(C:\Users\z\Desktop\tupian\10.13\5.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-89LKa4bW-1634122631644)(C:\Users\z\Desktop\tupian\10.13\4.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HC3peiKP-1634122631646)(C:\Users\z\Desktop\tupian\10.13\3.jpg)]
练习3:三角形,周长,面积
“”"
静态方法 - 不是三角形对象的消息,而是发给三角形类的消息
类方法 - 发给类的消息(比静态方法多一个参数,代表接受消息的类)
静态方法,类方法是一样的,类方法多一个参数,类参数可以得到和三角形相关的信息
Triangle.check_sides(a, b, c)
“”"
# 自己练习3:
class Triangle: # 三角形
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
def is_triangle(self):
return ((self.a + self.b) > self.c) and ((self.a + self.c) > self.b) and ((self.c + self.b) > self.a)
def perimeter(self):
return self.a + self.b + self.c
def area(self):
p = self.a + self.b + self.c
return (p/2*(p-self.a)(p-self.b)(p-self.c))**0.5
triangle = Triangle(1, 2, 3)
if triangle.is_triangle():
triangle.perimeter()
triangle.area()
else:
print('不符合三角形构成的条件')
class Triangle: # 三角形
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
# @classmethod
# def is_valid_sides(cls, a, b, c):
# return a + b > c and b + c > a and a + c > b
@staticmethod # 静态方法,发给类的消息,装饰器
def check_sides(a, b, c):
return a + b > c and b + c > a and a + c > b
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())# 切割默认是空格,字符串强制转换成float
if Triangle.check_sides(a, b, c):
tri = Triangle(a, b, c)
print(f'三角形周长:{tri.perimeter()}')
print(f'三角形面积:{tri.area()}')
print('无法构成三角形')
if __name__ == '__main__':#快捷方式
main()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TNk9Ebob-1634122631649)(C:\Users\z\Desktop\tupian\10.13\7.jpg)]
3、扑克牌游戏案例***
*****扑克游戏案例(反复推敲),有哪些类?对应的对象有哪些属性和方法?(名词-类/属性,动词-行为)
牌 - 一张 - 属性:花色/点数 - 行为:显示牌面,比大小
扑克 - 54张 - 属性:装54张牌的列表;- 行为:洗牌/发牌
玩家 - ID/昵称/手牌(列表);-行为:摸牌/打牌/整理手牌
less than – > lt --> <
great than --> gt --> >
equal to --> eq --> ==
黑杰克的游戏
后面还有哪些阶段?具体老师。
“”"
经验:符号常量总是优于字面常量!!!常量不易改
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):
if self.suite != other.suite:
return self.suite < other.suite
face1 = 14 if self.face == 1 else self.face
face2 = 14 if other.face == 1 else other.face
return face1 < face2
def show(self):
"""显示牌面"""
suite = ('♠', '♥', '♣', '♦')
faces = ('', 'A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K')
return f'{suite[self.suite]}{faces[self.face]}'
class Poker:
"""扑克"""
def __init__(self): # 推导式语法 shift+alt+上下键 上下移
self.cards = [Card(suite, face)
for suite in range(4)
for face in range(1, 14)]
self.index = 0
def shuffle(self): # 随机洗牌 方法 - 》random.函数
"""洗牌"""
self.index = 0
random.shuffle(self.cards)
def has_more(self):
"""有没有牌可以发出"""
return self.index < len(self.cards)
def deal(self):
"""发牌"""
# # return self.cards.pop() #列表.删除最后一张
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):
"""整理手牌??"""
# 列表的sort方法可以传入key参数来指定根据什么比较元素的大小,从而自定义排序的规则
# self.cards.sort(key=lambda card: card.face)
# self.cards.sort(key=lambda card: card.suite)
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)
# print(poker.cards)
# card1 = Card(HEART, 13)
# # 没有repr时输出情况
# # print(card1.show())
# card2 = Card(DIAMOND, 5)
# card3 = Card(SPADE, 6)
# print(card1, card2)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j943ucue-1634122631651)(C:\Users\z\Desktop\tupian\10.13\8.jpg)]
4、继承
“”"
继承:通过已有的类创建新的类,子类会得到父类的继承信息
python语言运行多重继承,一个类可以有多个父类
父类:提供继承信息的(基类,超类)
子类: 得到继承信息的(派生类)
公共的部分放在父类中,特有的部分写在子类中,子类通过继承父类,得到那些公共的部分
继承也是一种复用代码的方式
单一继承:一个类只能有唯一的父类,建议大家使用继承的时候使用单一继承
“”"
学生:姓名/年龄/年级;吃饭/玩耍/学习
老师:姓名/年龄/职称;吃饭/玩耍/授课
代码有很多种很坏的味道,但重复是最坏的一种
"""
class Person:
def __init__(self, name, age):
"""初始化方法
:param name: 姓名
:param age: 年龄
:param grade: 年级
"""
self.name = name
self.age = age
def eat(self):
"""吃饭"""
print(f'{self.name}正在吃饭.')
def play(self):
"""玩耍"""
print(f'{self.name}正在玩耍.')
"""
继承:通过已有的类创建新的类,子类会得到父类的继承信息
python语言运行多重继承,一个类可以有多个父类
父类:提供继承信息的(基类,超类)
子类: 得到继承信息的(派生类)
公共的部分放在父类中,特有的部分写在子类中,子类通过继承父类,得到那些公共的部分
继承也是一种复用代码的方式
单一继承:一个类只能有唯一的父类,建议大家使用继承的时候使用单一继承
"""
class Student(Person):
"""学生"""
def __init__(self, name, age, grade):
"""初始化方法
:param name: 姓名
:param age: 年龄
:param grade: 年级
"""
super().__init__(name, age) # 得到父类
self.grade = grade
def study(self, course_name):
"""学习
:param course_name: 课程名称
"""
print(f'{self.name}正在学习{course_name}.')
class Teacher(Person):
"""学生"""
def __init__(self, name, age, title):
"""初始化方法
:param name: 姓名
:param age: 年龄
:param title: 年级
"""
super().__init__(name, age)
self.title = title
def teach(self, course_name):
"""学习
:param course_name: 课程名称
"""
print(f'{self.name}正在讲授{course_name}.')
student = Student('王大锤', 18, '大一')
teacher = Teacher('陈来', 13, '教授')
student.play()
student.study('数学')
teacher.play()
teacher.teach('python数据')
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pHrGoTVM-1634122631652)(C:\Users\z\Desktop\tupian\10.13\9.jpg)]
day18作业-工资(月薪)结算系统
公司有三类员工,结算工资的方式是不一样的:
1.部门经理:15000元 / 月
2.程序员->计算工时-->200元/小时 * 本月工时
3.销售员 -> 底薪+提成 - > 1800元 + 本月销售额5%提出
给出员工信息列表,自动结算月薪
员工类
employee(员工),employer(雇主)
salary
manager
programmer
salesman
5、其他附录
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uE6cztFw-1634122631653)(C:\Users\z\Desktop\tupian\10.13\2.jpg)]
student = Student(‘王大锤’, 18, ‘大一’)
teacher = Teacher(‘陈来’, 13, ‘教授’)
student.play()
student.study(‘数学’)
teacher.play()
teacher.teach(‘python数据’)
[外链图片转存中...(img-pHrGoTVM-1634122631652)]
day18作业-工资(月薪)结算系统
公司有三类员工,结算工资的方式是不一样的:
1.部门经理:15000元 / 月
2.程序员->计算工时–>200元/小时 * 本月工时
3.销售员 -> 底薪+提成 - > 1800元 + 本月销售额5%提出
给出员工信息列表,自动结算月薪
员工类
employee(员工),employer(雇主)
salary
manager
programmer
salesman
### 5、其他附录
[外链图片转存中...(img-uE6cztFw-1634122631653)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zIQDksJP-1634122631654)(C:\Users\z\Desktop\tupian\10.13\6.jpg)]