一、练习:python自定义日期类型(补充)
class MyDate:
def __init__(self,year,month,day):
self.__normal_year = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
self.__leap_year = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
self.not_leap = 1
if self.check(year,month,day) == True:
self.__year = year
self.__month = month
self.__day = day
else:
raise ValueError('不是一个有效的日期')
def check(self,year,month,day):
if year < 0:
return False
if month > 12 or month < 1:
return False
if year % 4 == 0 and year % 100 != 0 or year % 400 == 0:
self.not_leap = 0
if day < 1 or day > self.__leap_year[month-1]:
return False
else:
if day < 1 or day > self.__normal_year[month - 1]:
return False
return True
def __str__(self):
return f'{self.__year}-{self.__month}-{self.__day}'
@property
def year(self):
return self.__year
@year.setter
def year(self,year):
self.__year = year
@property
def month(self):
return self.__month
@month.setter
def month(self, month):
self.__month = month
@property
def day(self):
return self.__day
@day.setter
def day(self, day):
self.__day = day
# d1 = MyDate()
# d2 = MyDate()
# d1.compare(d2)
# 0 ---> 相等 -1 ---》小于 1 ----》大于
def compare(self,other):
if self.__year > other.year:
return 1
elif self.__year == other.year:
if self.__month > other.month:
return 1
elif self.__month == other.month:
if self.__day == other.day:
return 0
elif self.__day > other.day:
return 1
else:
return -1
else:
return -1
else:
return -1
# d1 = MyDate(2016,10,12)
# dnew = d1.add_days(145)
# dnew = 20161106
def add_days(self, day_plus):
templst = []
while day_plus > 0:
if self.not_leap == 0:
templst = self.__leap_year
else:
templst = self.__normal_year
#加的天数没有超过本月总天数
if templst[self.month - 1] >= self.day + day_plus:
self.day += day_plus
day_plus = 0
# 加的天数超过了本月总天数,但是没有超过本年剩余天数?
else:
#本年还剩的天数
total = 0
for i in range(self.month,12):
total += templst[i]
day_plus -= (templst[self.month-1] - self.day)
#年不用动
if total >= day_plus:
while day_plus > 0:
self.month += 1
if day_plus > templst[self.month-1]:
day_plus -= templst[self.month-1]
else:
self.day = day_plus
day_plus = 0
else:
day_plus -= total
day_plus -= 1
self.year += 1
self.month = 1
self.day = 1
if self.year % 4 == 0 and self.year % 100 != 0 or self.year % 400 == 0:
self.not_leap = 0
def add_day(self, num):
while num:
if self.year % 4 == 0:
if self.day < self.__leap_year[self.month - 1]:
self.day += 1
num -= 1
else:
if self.month < 12:
self.month += 1
self.day = 1
num -= 1
else:
self.year += 1
self.month = 1
self.day = 1
num -= 1
else:
if self.day < self.__normal_year[self.month - 1]:
self.day += 1
num -= 1
else:
if self.month < 12:
self.month += 1
self.day = 1
num -= 1
else:
self.year += 1
self.month = 1
self.day = 1
num -= 1
self.__init__(self.year, self.month, self.day)
# d1 = MyDate(2016,10,12)
# d2 = MyDate(2016,12,12)
# days = d1.cal_interval(d2)----> d1-d2
# days---60
def cal_interval(self,date):
interval = 0
tmp = self
isSmall = False
if tmp.compare(date) == 0:
return interval
elif tmp.compare(date) < 0:
isSmall = True
tmp,date = date,tmp
while tmp.compare(date) > 0:
date.add_days(1)
interval += 1
if isSmall:
return -interval
else:
return interval
def get_day_in_the_year(self):
sum = 0
templst = []
if self.not_leap == 0:
templst = self.__leap_year
else:
templst = self.__normal_year
for month in range(self.__month-1):
sum += templst[month]
sum += self.__day
return sum
if __name__ == '__main__':
d1 = MyDate(1988,5,31)
print(d1)
d2 = MyDate(1988,8,31)
print(d2)
print(d1.cal_interval(d2))
print(d2.compare(d1))
d = MyDate(2019,11,19)
print(d.get_day_in_the_year())
print(d)
d.add_day(110)
print(d)
二、综合练习:综合实战---东软睿道运营仿真
需求 使用python面向对象思想,模拟仿真东软睿道公司运营整个过程
两个目的
- 综合运用学习过的知识点
- 运用面向对象思维解决实际问题
模拟睿道培训机构,从招生,到开班,到学员学习课程,到学员毕业,计算公司总收入,统计学员人数
一.类的识别
1.学生类
2.班级类
3.课程类
4.睿道公司类
5.收入明细类:
二.类的成员的定义(包括属性和方法)
1.学生类Student:姓名,经验值,勤奋程度(0.9),聪明程度(1.9),是否进入班级(true)
2.班级类Class:学员列表(List<Student>),开班日期,
3.课程类Course:课程名称,课时。
4.睿道公司类Company:班级列表(List<Class>)
,课程列表(List<Course>),总收入,收入明细。学员列表,未进入班级的学员列表
5.收入明细类:收入金额,收入日志
三.类的成员方法的定义
1.学生类:学习,缴费
2.班级类:开班,关班,上课
3.课程类:课程名,课时
4.睿道公司类:统计在校人数,统计全年收入,统计班级数....
5.收入明细类:
四.启动一个定时器,模拟东软睿道公司的运营情况
每一秒执行一个timer函数,模拟睿道一天的运营状况(睿道的一天):
1.招生(随机生成一个个学员对象,加入未开班班级,调用学员的缴费方法)
2.开班(需要判断是否满足条件[学员数量达到某个阈值])
3.各班级上课。(判断关班[所有课程全部完毕])
Course.py
class Course:
def __init__(self,course_name,course_hour):
self.course_name = course_name
self.course_hour = course_hour
def __str__(self):
return self.course_name
CourseTable.py
from Course import Course
class CourseTable:
def __init__(self):
self.tables = []
self.tables.append(Course("python", 5))
self.tables.append(Course("mysql", 3))
self.tables.append(Course("flask", 5))
self.tables.append(Course("django", 3))
self.tables.append(Course("tensorflow", 5))
self.tables.reverse()
Student
# 学生类Student:姓名,经验值,勤奋程度(0.9),聪明程度(1.9),是否进入班级(true)
# 学生类:学习,缴费
class Student:
def __init__(self):
self.name = ''
self.point = 0
self.hard_degree = 0
self.smart_degree = 0
self.is_enter_class = False
def pay_money(self):
return 20000
def study(self):
if self.is_enter_class == True:
self.point += 10 * self.hard_degree * self.smart_degree
print(f'{self.name}的经验值已经增长到{self.point}')
NeuEduClass.py
from datetime import datetime
from CourseTable import CourseTable
# // 2.班级类Class:学员列表(List<Student>),开班日期,班级名称
# //2.班级类:开班,关班,上课
# print(datetime.now())
class NeuEduClass:
class_num = 0
def __init__(self):
NeuEduClass.class_num += 1
self.class_name = ''
self.start_date = datetime.now()
self.students = []
self.course_table = CourseTable()
# //从课程表里取出一个课程,该课程课时减1,判断课时是否为0,如果大于0,重新放回课程表,
# //如果课程表为空,关闭班级
# stand_up函数返回一个值,is_closed,代表是否需要关班
def stand_up(self):
is_closed = False
cls = self.course_table.tables.pop()
cls.course_hour -= 1
print(f'{self.class_name}正在上{cls.course_name},还有{cls.course_hour}')
if cls.course_hour > 0:
self.course_table.tables.append(cls)
if len(self.course_table.tables) == 0:
is_closed = True
return is_closed
IncomeRecord
# //收入金额,收入日志
# //收到张三 10000
# //收到李四 10000
# //收到王五 10000
class IncomeRecord:
def __init__(self):
self.income = 0
self.log = ''
self.datetime = None
Company.py
# //4.睿道公司类Company:班级列表(List<Class>)
# //,课程列表(List<Course>),总收入,收入明细(List<IncomeRecord>)。学员列表,未进入班级的学员列表
# //睿道公司类:统计在校人数,统计全年收入,统计班级数....
from datetime import datetime
import random
from time import time
from IncomeRecord import IncomeRecord
from NeuEduClass import NeuEduClass
from Student import Student
class Company:
def __init__(self):
self.classes = []
self.income = 0
self.income_records = []
self.inschool_students = []
self.noclass_students = []
self.num = 5
#向学员收费
def add_money(self,student:Student):
money = student.pay_money()
self.income += money
ir = IncomeRecord()
ir.income = money
ir.datetime = datetime.now()
ir.log = f'{ir.datetime}收到{student.name}学费{money}元'
self.income_records.append(ir)
# 加入一个学生到未上课学员列表,考察当前列表长度,如果大于等于2人,开班(创建一个班级类对象,将学员添加到该班级)
def add_student_to_noclasslist(self,student:Student):
self.noclass_students.append(student)
size = len(self.noclass_students)
print(f'当前招生人数为{size}')
if size >= self.num:
#新建一个班级
class_new = NeuEduClass()
class_new.class_name = f'东软睿道Python{NeuEduClass.class_num}班'
self.classes.append(class_new)
print(f'{class_new.start_date}:{class_new.class_name}开班了')
#转移学生---》NeuEduClass(self.students)
for stu in self.noclass_students:
stu.is_enter_class = True
class_new.students.append(stu)
self.noclass_students.clear()
# //招生
# //new 一个学生对象,返回。
# //随机产生一个学员,先生成一个0-1之间的随机数
# //如果该随机数小于0.7,就返回一个新学员对象
# //否则,None
# 招生成功率70 %
# 返回值是一个学生对象(如果招生成果),是一个None(如果招生失败)
def get_student(self):
num = random.randint(1,10)
if num <= 7:
# // 根据系统当前时间生成一个时间戳,保证用户名不重复
# // 时间戳是当前时间距离19700101经过的毫秒数
stu = Student()
stu.name = f'张{time()}'
stu.point = num * 10
stu.hard_degree = random.randint(1,10)
stu.smart_degree = random.randint(1,10)
stu.is_enter_class = False
print(f'学员{stu.name}加入睿道学习,等待新班')
return stu
else:
print(f'很遗憾,本次招生没有成功')
return None
day_of_neuedu.py
import threading
import time
from Company import Company
# // 四.在main函数中启动一个定时器,模拟我们睿道公司的运营情况
# // 每一秒执行一个timer函数模拟睿道一天的运营状况(睿道的一天)。
# 0.判断一下今天是否休息
# // 1.招生(随机生成一个个学员对象,加入为开班班级,调用学员的缴费方法);
# // 2.开班(需要判断)
# // 3.各班级上课。(判断关班)
index = 0
def day_of_neuedu(company:Company):
global index
index += 1
#周末盘点
if index % 7 == 0:
stu_num = len(company.income_records)
total_income = sum(map(lambda x: x.income,company.income_records))
print('-' * 30 + f'周末休息盘点' + '-' * 30)
print(f'\033[1;35m截止目前睿道共培训学员{stu_num}名,公司总营收收入{total_income}元\033[0m')
print('-' * 30 + f'周末休息盘点' + '-' * 30)
time.sleep(3)
else:
print('-' * 30 + f'东软睿道美好的一天开始了,各部门员工紧张忙碌了起来' + '-' * 30)
print('市场部开始接待客户')
stud = company.get_student()
if stud != None:
company.add_money(stud)
company.add_student_to_noclasslist(stud)
print(f'当前有{len(company.classes)}在上课')
if len(company.classes) > 0:
print('实施部的老师们开始上课了')
class_removed = [] #待关闭的班级
for cls in company.classes:
is_closed = cls.stand_up()
for stu in cls.students:
stu.study()
if is_closed == True:
class_removed.append(cls)
for del_cls in class_removed:
print(f'{del_cls.class_name}学生结业了,全部找到高薪工作,走上人生巅峰,迎娶白富美')
company.classes.remove(del_cls)
timer = threading.Timer(6, day_of_neuedu, [company])
timer.start()
company = Company()
timer = threading.Timer(6,day_of_neuedu,[company])
timer.start()
三、补充:Python中的计时器
注意:
- 其他语言中:一次性定时器,周期性定时器
- Python中:只有一次性定时器
#引入库 threading
import threading
#定义函数
def fun_timer(msg,count):
print('hello timer'+msg+str(count)) #打印输出
global timer #定义变量
timer = threading.Timer(1,fun_timer,[msg,count])
timer.start() #启用定时器
#定时器构造函数主要有2个参数,第一个参数为时间处理函数(多少秒运行一次),第二个参数为时间处理函数函数名
#第三个参数为传递给fun_timer的参数列表
#1秒后调用函数fun_timer
timer = threading.Timer(1,fun_timer,['hello',5]) #首次启动
timer.start()
四、异常处理
1.异常的概念
- 程序在运行时,如果 Python 解释器 遇到 到一个错误,会停止程序的执行,并且提示一些错误信息,这就是 异常
- 程序停止执行并且提示错误信息 这个动作,我们通常称之为:抛出(raise)异常
2. 异常捕获完整语法
try:
# 尝试执行的代码
pass
except 错误类型1:
# 针对错误类型1,对应的代码处理
pass
except 错误类型2:
# 针对错误类型2,对应的代码处理
pass
except (错误类型3, 错误类型4):
# 针对错误类型3 和 4,对应的代码处理
pass
except Exception as result: # 包括其他所有情况
# 打印错误信息
print(result)
else:
# 没有异常才会执行的代码
pass
finally:
# 无论是否有异常,都会执行的代码
print("无论是否有异常,都会执行的代码")
注意:
- else 只有在没有异常时才会执行的代码
- finally 无论是否有异常,都会执行的代码
- 异常处理 try 之后 except 和 else 只能进一个
- finally一般用来关闭文件或者释放内存
示例:
try:
num = int(input("请输入整数:"))
result = 8 / num
print(result)
except ValueError:
print("请输入正确的整数")
except ZeroDivisionError:
print("除 0 错误")
except Exception as result:
print("未知错误 %s" % result)
else:
print("正常执行")
finally:
print("执行完成,但是不保证正确")
3. 抛出 raise 异常
主动抛出异常,没有异常创造异常也要异常。
应用于某些场景需要特定条件才能进入,不达到条件则主动抛出异常。
示例:
def input_password():
# 1\. 提示用户输入密码
pwd = input("请输入密码:")
# 2\. 判断密码长度,如果长度 >= 8,返回用户输入的密码
if len(pwd) >= 8:
return pwd
# 3\. 密码长度不够,需要抛出异常
# 1> 创建异常对象 - 使用异常的错误信息字符串作为参数
ex = Exception("密码长度不够")
# 2> 抛出异常对象
raise ex
try:
user_pwd = input_password()
print(user_pwd)
except Exception as result:
print("发现错误:%s" % result)
4. 自定义异常
class MyException(Exception): #让MyException类继承Exception
def __init__(self,name,age):
self.name = name
self.age = age
try:
#知识点:主动抛出异常,就是实例化一个异常类
raise MyException("zhansgan",19) #实例化一个异常,实例化的时候需要传参数
except MyException as obj: #这里体现一个封装,
print(obj.age,obj.name) #捕获的就是MyException类携带过来的信息
except Exception as obj: #万能捕获,之前的可能捕获不到,这里添加Exception作为保底
print(obj)
补充:
打印彩色输出:
print(f'\033[1;35m粉色啦啦啦\033[0m')
网友评论