Python正式课第十二天

一、练习: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')
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,607评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,239评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,960评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,750评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,764评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,604评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,347评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,253评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,702评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,893评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,015评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,734评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,352评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,934评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,052评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,216评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,969评论 2 355

推荐阅读更多精彩内容

  • python提供了两个非常重要的功能来处理python程序在运行中出现的异常和错误。你可以使用该功能来调试pyth...
    _宁采臣阅读 1,025评论 0 10
  • http://python.jobbole.com/85231/ 关于专业技能写完项目接着写写一名3年工作经验的J...
    燕京博士阅读 7,579评论 1 118
  • Python语言特性 1 Python的函数参数传递 看两个如下例子,分析运行结果: 代码一: a = 1 def...
    时光清浅03阅读 488评论 0 0
  • 晚上,女儿打电话: 麻麻,我给你买的衣服应该到了,记得去快递那里拿啊。 好吧,到时候试试看,不合适就退。 应该很合...
    夏薇AN阅读 263评论 0 3
  • 今天老公回老家,老大一睡醒就找爸爸呢?我说爸爸去坐车了,她说怎么这么快啊! 孩子的感受是1 舍不得爸爸,想念爸爸。...
    简单的我燕凤阅读 94评论 0 0