作业 1. 三合一 2. 当天练习独立完成 3. 将员工管理系统分为4个模块 employee_system.py 4. (选做)完成2048上下移动函数 -- 自定义矩阵转置函数,实现行列颠倒 -- 向上移动(矩阵转置,调用向左移动函数,矩阵转置) -- 向下移动(矩阵转置,调用向右移动函数,矩阵转置)
三
class EmployeeModel: def __init__(self, eid=0, did=0, name="", money=0): self.eid = eid self.did = did self.name = name self.money = money
from model import EmployeeModel class EmployeeController: """ 商品信息控制器 """ __start_id = 1001 @classmethod def __set_employee_id(cls, emp): emp.eid = cls.__start_id cls.__start_id += 1 def __init__(self): self.__all_employee = [] # type:List[EmployeeModel] @property def all_employee(self): return self.__all_employee def add_employee(self, emp: EmployeeModel): """ 添加商品信息 :param employee:需要添加的商品信息 """ EmployeeController.__set_employee_id(emp) self.__all_employee.append(emp) def remove_employee(self, eid: int) -> bool: """ 根据商品编号删除商品信息 :param cid:商品编号 :return:是否删除成功 """ for i in range(len(self.__all_employee)): if self.__all_employee[i].eid == eid: del self.__all_employee[i] return True return False def update_employee(self, commodity: EmployeeModel) -> bool: """ 修改商品信息 :param commodity:商品信息 :return:是否删除成功 """ for item in self.__all_employee: if item.eid == commodity.eid: item.__dict__ = commodity.__dict__ return True return False
from model import EmployeeModel class EmployeeView: """ 商品信息视图 """ def __init__(self, controller): self.__controller = controller # type:EmployeeController def main(self): while True: self.__display_menu() self.__select_menu() def __display_menu(self): print("1 添加员工") print("2 显示员工") print("3 删除员工") print("4 修改员工") def __select_menu(self): item = input("请输入您的选项:") if item == "1": self.__input_employee() elif item == "2": self.__display_employees() elif item == "3": self.__delete_employee() elif item == "4": self.__modify_employee() def __input_employee(self): employee = EmployeeModel() employee.name = input("请输入员工名称:") employee.did = int(input("请输入部门编号:")) employee.money = int(input("请输入员工工资:")) self.__controller.add_employee(employee) def __display_employees(self): for item in self.__controller.all_employee: print(item.__dict__) def __delete_employee(self): cid = int(input("请输入员工编号:")) if self.__controller.remove_employee(cid): print("删除成功") else: print("删除失败") def __modify_employee(self): employee = EmployeeModel() employee.eid = int(input("请输入员工编号:")) employee.name = input("请输入员工名称:") employee.did = int(input("请输入部门编号:")) employee.money = int(input("请输入员工工资:")) if self.__controller.update_employee(employee): print("修改成功") else: print("修改失败")
""" pyc文件让程序运行不用从头开始。节约时间与性能 """ from bll import EmployeeController #alt+enter导入 from usl import EmployeeView if __name__ == '__main__': view = EmployeeView(EmployeeController()) view.main()
四
""" 2048 游戏核心算法 谈架构 显示(界面)与控制(算法)分离 谈算法 1. 高内聚:类内部的各个方法相可以互调用并且关系紧密(代码复用高) 上下移动 -矩阵转置-> 左右移动 向左移动 --> 合并数据 --> 零元素后移 向右移动 -翻转-> 合并数据 --> 零元素后移 2. 低耦合:类与类之间关系不大,修改一个类不影响用另外一个类 类内部高内聚,类与类低耦合 3. 降维思想: 将二维列表的操作,改为对一维列表的操作. """ list_merge = [2, 0, 0, 2] # 做成全局的,省得下面好几个函数定义形式参数了 # 为什么函数不做返回值,因为所有函数直接操作的都是可变对象,所以返回值不写 def zero_to_end(): """ 零元素向后移动 思想:从后向前判断,如果是0则删除,在末尾追加. """ for i in range(len(list_merge) - 1, -1, -1): if list_merge[i] == 0: del list_merge[i] list_merge.append(0) # zero_to_end() # print(list_merge) def merge(): """ 合并数据 核心思想:零元素后移,判断是否相邻相同。如果是则合并. """ zero_to_end() for i in range(len(list_merge) - 1): if list_merge[i] == list_merge[i + 1]: list_merge[i] += list_merge[i + 1] del list_merge[i + 1] list_merge.append(0) # 加分 # merge() # print(list_merge) map = [ [2, 0, 0, 2], [4, 2, 0, 2], [2, 4, 2, 4], [0, 4, 0, 4], ] def move_left(): global list_merge for line in map: list_merge = line merge() # move_left() # print(map) def move_right(): global list_merge for line in map: # 从右向左获取数据形成新列表 list_merge = line[::-1] # 处理数据 merge() # 将处理后的数据再从右向左还给map line[::-1] = list_merge # move_right() # print(map) def square_matrix_transposition(): for c in range(1, len(map)): # 1 2 3 for r in range(c, len(map)): map[r][c - 1], map[c - 1][r] = map[c - 1][r], map[r][c - 1] def move_up(): """ 向上移动 思想: 转置 move_left 转置 """ square_matrix_transposition() move_left() square_matrix_transposition() # 6. 向下移动 def move_down(): """ 向下移动 思想: 转置 move_right 转置 :return: """ square_matrix_transposition() move_right() square_matrix_transposition() # move_up() move_down() print(map)
异常处理 Error
异常
-
定义:运行时检测到的错误。
-
现象:当异常发生时,程序不会再向下执行,而转到函数的调用语句。
-
常见异常类型:
-- 名称异常(NameError):变量未定义。
-- 类型异常(TypeError):不同类型数据进行运算。
-- 索引异常(IndexError):超出索引范围。
-- 属性异常(AttributeError):对象没有对应名称的属性。
-- 键异常(KeyError):没有对应名称的键。
--值异常(ValueError):输入错误值
-- 异常基类 (父类)Exception。
处理
-
语法:
try:
可能触发异常的语句
except 错误类型 1 [as 变量 1]:
处理语句 1
except 错误类型 2 [as 变量 2]:
处理语句 2
except Exception [as 变量 3]:
不是以上错误类型的处理语句
else:
未发生异常的语句
finally:
无论是否发生异常的语句
-
作用:将程序由异常状态转为正常流程。
-
说明:
as 子句是用于绑定错误对象的变量,可以省略
except 子句可以有一个或多个,用来捕获某种类型的错误。
else 子句最多只能有一个。
finally 子句最多只能有一个,如果没有 except 子句,必须存在。
如果异常没有被捕获到,会向上层(调用处)继续传递,直到程序终止运行。
""" 异常处理 异常处理不适用以下语法错误,适用于解决逻辑错误(往往数据不在有效规定范围) """ """ list01 = [] print(list01[2]) print(abc) """ def div_apple(apple_count): person_count = int(input("people number")) result = apple_count / person_count print(f"每个人{result}个") div_apple(10) # ValueError:控制台输入不合法数据 print("输入异常也继续执行后续逻辑") # 整个程序全部崩溃,需要提出一种错误处理机制
""" 通过调试观察发现:程序执行过程 1-->2--->3 出错 -->2-->1 """ #3 def div_apple(apple_count): person_count = int(input("people number")) result = apple_count/person_count print(f"每个人{result}个") #2 def main(): div_apple(10) #1 main() print("输入异常也继续执行后续逻辑")
""" 解决方案:异常处理作用让程序错误了,也可以往下执行 """ # 写法1:包治百病(掌握) def div_apple(apple_count): try: person_count = int(input("people number")) result = apple_count / person_count print(f"每个人{result}个") except Exception: # 现在直接可以等价于excpet: Exception都不用写了 print("分苹果失败") # 写法2:对症下药Exception换成ValueError与ZeroDivisionError等等 def div_apple(apple_count): # 名称相同取就近更新的函数 try: person_count = int(input("people number")) result = apple_count / person_count print(f"每个人{result}个") except ValueError: print("输入不是整数") except ZeroDivisionError: print("输入不能是零") # 写法3 # 无论是否发生错误都一定执行的结果,并且不执行后续逻辑 # 以上代码成功就不执行异常处理代码,然后执行后续逻辑 def div_apple(apple_count): # 名称相同取就近更新的函数 try: person_count = int(input("people number")) result = apple_count / person_count print(f"每个人{result}个") finally: # 分苹果成功失败都执行下面语句 print("不知道分苹果还是失败,我都执行") # 写法4 # else作用:没有错误才执行的逻辑 def div_apple(apple_count): # 名称相同取就近更新的函数 try: person_count = int(input("people number")) result = apple_count / person_count print(f"每个人{result}个") except: print("分苹果失败") else: print("分苹果成功") def main(): div_apple(10) main() print("后续逻辑")
""" 练习:创建函数,在终端中录入int类型成绩。 如果格式不正确,重新输入。 效果: """ # 虽然异常处理解决了不报错问题,但可以通过结合循环方式实现输入出错也可以重写执行 def get_score(): while True: try: score = int(input("please")) return score except: print("重写输入") score = get_score() print("成绩是 %d" % score)
对学生信息管理系统输入异常进行改造代码
from model import StudentModel from bll import StudentController class StudentView: """ 学生视图:处理界面逻辑 """ def __init__(self, controller=None): self.__controller = controller # type:StudentController def __display_menu(self): print("按1键录入学生信息") print("按2键显示学生信息") print("按3键删除学生信息") print("按4键修改学生信息") def __get_right(self, message): while True: try: num = int(input(message)) return num except: print("输入有误,重新输入") def __select_menu(self): item = input("请输入您的选项:") if item == "1": # 先写方法调用,再alt+回车自动生成 self.__input_student() elif item == "2": self.__display_students() elif item == "3": self.__delete_student() elif item == "4": self.__modify_student() def __input_student(self): stu = StudentModel() stu.name = input("请输入学生姓名:") stu.score = self.__get_right("请输入学生成绩:") stu.age = self.__get_right("请输入学生年龄:") self.__controller.add_student(stu) print("添加成功") def main(self): """ 入口 """ while True: self.__display_menu() self.__select_menu() def __display_students(self): for stu in self.__controller.students: print(stu) def __delete_student(self): sid = self.__get_right("请输入学生编号:") if self.__controller.remove_student(sid): print("删除成功") else: print("删除失败") def __modify_student(self): stu = StudentModel() stu.sid = self.__get_right("请输入需要修改的学生编号:") stu.name = input("请输入需要修改的学生姓名:") stu.age = self.__get_right("请输入学生年龄:") stu.score = self.__get_right("请输入学生成绩:") if self.__controller.update_student(stu): print("修改成功") else: print("修改失败")
from bll import StudentController from usl import StudentView #这个文件标蓝了,前提是其他同名文件不要标蓝,不然系统会找错文件 # 如果当前是主模块,才执行入口逻辑 if __name__ == '__main__': try: controller = StudentController() view =StudentView(controller) view.main() except: print("这叫全局异常处理,不应该是我们应用层开发人员做的") #异常处理是在哪一步错的,就哪一部处理,在这步处理不了,再返回上层次处理。 #因此异常处理精髓是就近处理原则
raise 语句
-
作用:抛出一个错误,让程序进入异常状态。与try expect搭配使用
-
目的:在程序调用层数较深时,向主调函数传递错误信息要层层 return 比较麻烦,
所以人为抛出异常,可以直接快速传递错误信息。
""" 人为创造异常: 目的是快速传递消息 快速理解:这叫慢1-->2-->3-->2--->1 这叫快1-->2-->3-->1 """ class Wife: def __init__(self, age=0): self.age = age # 2 @property def age(self): return self.__age @age.setter def age(self, value): if 20 < value < 30: # 3 self.__age = value else: # 人为创造异常,主动制造 raise Exception("设置年龄有误") while True: try: # 接收异常 jn = Wife(int(input("please"))) # 1 print(jn.age) break except Exception as error: print(error.args) # 将上面设定的字符串打印 # 或者except: # print("年龄范围输入过了")
迭代
每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值。例如:循环获取容器中的元素。
可迭代对象 iterable
-
定义:具有iter函数的对象,可以返回迭代器对象。
-
语法
-- 创建:
class 可迭代对象名称:
def iter(self):
return 迭代器
-- 使用:
for 变量名 in 可迭代对象:
语句
-
原理:
迭代器 = 可迭代对象.iter()
while True:
try:
print(迭代器.next()
except StopIteration:
""" 可迭代对象 迭代:iteration :重复下一个元素 迭代器:iterator:执行迭代过程的对象iterator 可迭代 iterable:可以创建迭代器的对象message 面试题目:for能够参与for循环条件是什么? 答:具有iter函数能够创建迭代器对象 """ message = "abcdefg" # for item in message: # print(item) #for循环原理 #1.获取迭代器对象 iterator = message.__iter__() #2.获取下一个元素 while True: try: item = iterator.__next__() print(item) #3 如果停止迭代推出循环 except StopIteration: break
""" 练习 1:创建列表,使用迭代思想,打印每个元素. 练习 2:创建字典,使用迭代思想,打印每个键值对. """ list01 = [1, 2, 3, 4, 5] iterator = list01.__iter__() while True: try: item = iterator.__next__() print(item) except: break dict01 = {1: 'a', 2: 'b', 3: 'c'} iterator = dict01.__iter__() while True: try: item = iterator.__next__() print(item, dict01[item]) except: break
""" 迭代器 """ # 声明:下列代码主要用于学习创建迭代器 class StudentIterator: """ 学生迭代器 """ def __init__(self, data): self.__data = data self.__index = -1 def __next__(self): if self.__index == len(self.__data) - 1: raise StopIteration() self.__index += 1 return self.__data[self.__index] class StudentController: """ 学生可迭代对象 """ def __init__(self): self.__students = [] def add_student(self, stu): self.__students.append(stu) def __iter__(self): return StudentIterator(self.__students) controller = StudentController() controller.add_student("郭世鑫") controller.add_student("刘兰涛") controller.add_student("穆东宇") # for item in controller: # print(item) # iterator = controller.__iter__() while True: try: item = iterator.__next__() print(item) # except StopIteration: break
""" 图形状生迭代器 """ class ComodityIterator: def __init__(self, data): self.__data = data self.__index = -1 def __next__(self): if self.__index == len(self.__data) - 1: raise StopIteration() self.__index += 1 return self.__data[self.__index] class GraphicController: def __init__(self): self.__graphics = [] def add_graphic(self, gra): self.__graphics.append(gra) def __iter__(self): return ComodityIterator(self.__graphics) controller = GraphicController() controller.add_graphic("圆形") controller.add_graphic("矩形") controller.add_graphic("三角形") for item in controller: print(item) iterator = controller.__iter__() while True: try: item = iterator.__next__() print(item) # except StopIteration: break
""" 商品生迭代器 """ class ComodityIterator: def __init__(self, data): self.__data = data self.__index = -1 def __next__(self): if self.__index == len(self.__data) - 1: raise StopIteration() self.__index += 1 return self.__data[self.__index] class CommodityController: def __init__(self): self.__comoditys = [] def add_commodity(self, com): self.__comoditys.append(com) def __iter__(self): return ComodityIterator(self.__comoditys) controller = CommodityController() controller.add_commodity("屠龙刀") controller.add_commodity("倚天剑") controller.add_commodity("芭比娃娃") for item in controller: print(item) iterator = controller.__iter__() while True: try: item = iterator.__next__() print(item) # except StopIteration: break
# 练习 3:创建自定义 range 类,实现下列效果. # class NumberIterator: # def __init__(self, data): # self.__data = data # self.__index = -1 # # def __next__(self): # if self.__index == len(self.__data) - 1: # raise StopIteration() # self.__index += 1 # return self.__data[self.__index] # # # # class MyRange: # def __init__(self,num): # self.data = [] # for i in range(num): # self.data.append(i) # # def __iter__(self): # return NumberIterator(self.data) # # # for number in MyRange(5): # print(number) # 0 1 2 3 4 class MyRangeIterator: def __init__(self, end): self.__number = -1 self.__end = end def __next__(self): if self.__number == self.__end - 1: raise StopIteration() self.__number += 1 return self.__number class MyRange: def __init__(self, stop): self.__stop = stop def __iter__(self): return MyRangeIterator(self.__stop) # 循环一次 计算一次 返回一次 不攒着 根本不费内存 for number in MyRange(2000000): print(number) # 0 1 2 3 4 mr = MyRange(5) iterator = mr.__iter__() while True: try: item = iterator.__next__() print(item) # 0 1 2 except StopIteration: break
迭代器对象 iterator
-
定义:可以被 next()函数调用并返回下一个值的对象。
-
语法
class 迭代器类名:
def init(self, 聚合对象):
self.聚合对象= 聚合对象
def next(self):
if 没有元素:
raise StopIteration
return 聚合对象元素
-
说明:
-- 聚合对象通常是容器对象。
-
作用:使用者只需通过一种方式,便可简洁明了的获取聚合对象中各个元素,而又
无需了解其内部结构。
生成器函数
-
定义:含有 yield 语句的函数,返回值为生成器对象。
-
语法
-- 创建:
def 函数名():
…
yield 数据
…
-- 调用:
for 变量名 in 函数名():
语句
-
说明:
-- 调用生成器函数将返回一个生成器对象,不执行函数体。
-- yield 翻译为”产生”或”生成”
-
执行过程:
(1) 调用生成器函数会自动创建迭代器对象。
(2) 调用迭代器对象的next()方法时才执行生成器函数。
(3) 每次执行到 yield 语句时返回数据,暂时离开。
(4) 待下次调用next()方法时继续从离开处继续执行。
-
原理:生成迭代器对象的大致规则如下
-- 将 yield 关键字以前的代码放在 next 方法中。
-- 将 yield 关键字后面的数据作为 next 方法的返回值。
""" yield ---生成器--浅出 """ class StudentController: """ 学生可迭代对象 """ def __init__(self): self.__students = [] def add_student(self, stu): self.__students.append(stu) def __iter__(self): # 生成代码的大致规则: # 1. 将yield关键字前面的代码作为__next__函数体 # 2. 将yield关键字后面的数据作为__next__返回值 index = 0 yield self.__students[index] index += 1 yield self.__students[index] index += 1 yield self.__students[index] controller = StudentController() controller.add_student("郭世鑫") controller.add_student("刘兰涛") controller.add_student("穆东宇") # for item in controller: # print(item) # iterator = controller.__iter__()#调用iter函数,函数体不干,因为这个函数在next函数里面 while True: try: item = iterator.__next__() print(item) # except StopIteration: break
""" MyRange 2.0 精辟在yelid 直接取代了迭代器对象(里面有 iter 与 创造异常) """ class MyRange: def __init__(self, stop): self.__stop = stop def __iter__(self): number = 0 yield number number += 1 yield number number += 1 yield number number += 1 # 循环一次 计算一次 返回一次 for number in MyRange(3): print(number) # 0 1 2 mr = MyRange(3) iterator = mr.__iter__() while True: try: item = iterator.__next__() print(item) # 0 1 2 except StopIteration: break #写成while循环传入的参数就有效了