当前位置:   article > 正文

头歌python实训通关七——面向对象程序设计——进阶_头歌python分支结构工资计算答案

头歌python分支结构工资计算答案

第1关:工资结算系统

任务描述

本关任务:某公司有三种类型的员工 分别是部门经理、程序员和销售员,需要设计一个工资结算系统 根据提供的员工信息来计算月薪,部门经理的月薪是每月固定15000元,程序员的月薪按本月工作时间计算每小时150元,销售员的月薪是1200元的底薪加上销售额5%的提成。你需要编写不同职位的工资结算方法。

相关知识

为了完成本关任务,你需要掌握:1.类和对象,2.装饰器

编程要求

根据提示,在右侧编辑器补充代码,根据提示,完成经理程序员销售员三个类别的相关内容。

测试说明

根据程序中的提示,完成相应类代码的编写。 提示:在本题测试脚本中,初始数据为``` Manager('刘备'), Programmer('诸葛亮'), Manager('曹操'), Salesman('荀彧'), Salesman('吕布'), Programmer('张辽'), Programmer('赵云') 且工作时长默认为7,销售额默认为100

```

  1. """
  2. 某公司有三种类型的员工 分别是部门经理、程序员和销售员
  3. 需要设计一个工资结算系统 根据提供的员工信息来计算月薪
  4. 部门经理的月薪是每月固定15000元
  5. 程序员的月薪按本月工作时间计算 每小时150元
  6. 销售员的月薪是1200元的底薪加上销售额5%的提成
  7. """
  8. from abc import ABCMeta, abstractmethod
  9. class Employee(object, metaclass=ABCMeta):
  10. """员工"""
  11. def __init__(self, name):
  12. """
  13. 初始化方法
  14. :param name: 姓名
  15. """
  16. self._name = name
  17. @property
  18. def name(self):
  19. return self._name
  20. @abstractmethod
  21. def get_salary(self):
  22. """
  23. 获得月薪
  24. :return: 月薪
  25. """
  26. pass
  27. class Manager(Employee):
  28. """部门经理"""
  29. def get_salary(self):
  30. return 15000.0
  31. class Programmer(Employee):
  32. """程序员"""
  33. def __init__(self, name, working_hour=0):
  34. super().__init__(name)
  35. self._working_hour = working_hour
  36. @property
  37. def working_hour(self):
  38. return self._working_hour
  39. @working_hour.setter
  40. def working_hour(self, working_hour):
  41. self._working_hour = working_hour if working_hour > 0 else 0
  42. def get_salary(self):
  43. return 150.0 * self._working_hour
  44. class Salesman(Employee):
  45. """销售员"""
  46. def __init__(self, name, sales=0):
  47. super().__init__(name)
  48. self._sales = sales
  49. @property
  50. def sales(self):
  51. return self._sales
  52. @sales.setter
  53. def sales(self, sales):
  54. self._sales = sales if sales > 0 else 0
  55. def get_salary(self):
  56. return 1200.0 + self._sales * 0.05

第2关:设计LFU缓存类

任务描述

本关任务:编写一个具有put,get功能的LFU Cache类

相关知识

  • 缓存算法广泛存在于各种软件中,其中有一些著名的缓存方法,如LFU替换算法,LFU(Least Frequently Used)算法根据数据的历史访问频率来淘汰数据,其核心思想是“如果数据过去被访问多次,那么将来被访问的频率也更高”。LFU实现方式是这个缓存算法使用一个计数器来记录条目被访问的频率。通过使用LFU缓存算法,最低访问数的条目首先被移除。LFU的每个数据块都有一个引用计数,所有数据块按照引用计数排序,具有相同引用计数的数据块则按照时间排序。
  • LFU缓存的实现:LFU(Least Frequently Used)是根据频率维度来选择将要淘汰的元素,即删除访问频率最低的元素。如果两个元素的访问频率相同,则淘汰最久没被访问的元素。那么LFU淘汰的时候会选择两个维度,先比较频率,选择访问频率最小的元素;如果频率相同,则按时间维度淘汰掉最久远的那个元素。
  • 因此,LFU可以通过两个哈希表再加上多个双链表来实现:
  • 第一张哈希表是key-value的哈希表,如下图所示。其中key就是输入的key。value是一个节点对象。这个节点对象Node包含了key,value,以及频率,这个Node又会出现在第二个哈希表的value中。Node中重复包含了key,这是因为某些情况下我们不是通过key-value哈希表拿到Node的,而是通过其他方式获得了Node,之后需要用Node中的key去key-value哈希表中做一些操作,所以Node中包含了一些冗余信息。 

  • 第二张哈希表是频率哈希表,如下图所示。这张哈希表中的key是频率,也就是元素被访问的频率(被访问了1次,被访问了两次等),它的value是一个双向链表,图一中的Node对象,在图二中同样存在,图二中的Node其实是双向链表中的一个节点。图一中的Node对象中包含了一个冗余的key,其实它还包含了一个冗余的频率值,因为某些情况下,我们需要通过Node对象中的频率值,去频率哈希表中做查找,所以也需要一个冗余的频率值。 

  • 因此,我们将两个哈希表整合可以发现,整个完整的LFU cache结构如下图所示。 

     现在请你完成一个具有put,get功能的LFU Cache类.
  • put、get的逻辑如下: 

编程要求

根据提示,在右侧编辑器补充代码,实现完整的LFU Cache类

测试说明

平台会对你编写的代码进行测试:

测试输入: ["LFUCache", "put", "put", "get", "put", "get", "get", "put", "get", "get", "get"] [[2], [1, 1], [2, 2], [1], [3, 3], [2], [3], [4, 4], [1], [3], [4]] 预期输出: [None, None, 1, None, -1, 3, None, -1, 3, 4]

  1. from operator import methodcaller
  2. class Node(object):
  3. """
  4. 双链表中的链表节点对象
  5. """
  6. def __init__(self, key=None, value=None, freq=0):
  7. """
  8. Args:
  9. key:对应输入的key
  10. value:对应输入的value
  11. freq:被访问的频率
  12. pre:指向前一个节点的指针
  13. next:指向后一个节点的指针
  14. """
  15. self.key = key
  16. self.value = value
  17. self.freq = freq
  18. self.pre = None
  19. self.next = None
  20. class LinkedList(object):
  21. """
  22. 自定义的双向链表
  23. """
  24. def __init__(self):
  25. """
  26. Args:
  27. __head:双向链表的头结点
  28. __tail:双向链表的尾节点
  29. """
  30. self.__head = Node()
  31. self.__tail = Node()
  32. self.__head.next = self.__tail
  33. self.__tail.pre = self.__head
  34. def insertFirst(self, node):
  35. """
  36. 将指定的节点插入到链表的第一个位置
  37. Args:
  38. node:将要插入的节点
  39. """
  40. node.next = self.__head.next
  41. self.__head.next.pre = node
  42. self.__head.next = node
  43. node.pre = self.__head
  44. def delete(self, node):
  45. """
  46. 从链表中删除指定的节点
  47. Args:
  48. node:将要删除的节点
  49. """
  50. if self.__head.next == self.__tail:
  51. return
  52. node.pre.next = node.next
  53. node.next.pre = node.pre
  54. node.next = None
  55. node.pre = None
  56. def getLast(self):
  57. """
  58. 从链表中获取最后一个节点
  59. Returns:
  60. 双向链表中的最后一个节点,如果是空链表则返回None
  61. """
  62. if self.__head.next == self.__tail:
  63. return None
  64. return self.__tail.pre
  65. def isEmpty(self):
  66. """
  67. 判断链表是否为空,除了head和tail没有其他节点即为空链表
  68. Returns:
  69. 链表不空返回True,否则返回False
  70. """
  71. return self.__head.next == self.__tail
  72. class LFUCache(object):
  73. """
  74. 自定义的LFU缓存
  75. """
  76. def __init__(self, capacity):
  77. """
  78. Args:
  79. __capacity:缓存的最大容量
  80. __keyMap: key->Node 这种结构的字典
  81. __freqMap:freq->LinkedList 这种结构的字典
  82. __minFreq:记录缓存中最低频率
  83. """
  84. self.__capacity = capacity
  85. self.__keyMap = dict()
  86. self.__freqMap = dict()
  87. self.__minFreq = 0
  88. def get(self, key):
  89. """
  90. 获取一个元素,如果key不存在则返回-1,否则返回对应的value
  91. 同时更新被访问元素的频率
  92. Args:
  93. key:要查找的关键字
  94. Returns:
  95. 如果没找到则返回-1,否则返回对应的value
  96. """
  97. #你的代码在这里#
  98. if key not in self.__keyMap:
  99. return -1
  100. node = self.__keyMap[key]
  101. self.__increment(node)
  102. return node.value
  103. def put(self, key, value):
  104. """
  105. 插入指定的key和value,如果key存在则更新value,同时更新频率
  106. 如果key不存并且缓存满了,则删除频率最低的元素,并插入新元素
  107. 否则,直接插入新元素
  108. Args:
  109. key:要插入的关键字
  110. value:要插入的值
  111. """
  112. #你的代码在这里#
  113. if key in self.__keyMap:
  114. node = self.__keyMap[key]
  115. node.value = value
  116. self.__increment(node)
  117. else:
  118. if self.__capacity==0:
  119. return
  120. if len(self.__keyMap)==self.__capacity:
  121. self.__removeMinFreqElement()
  122. node = Node(key,value,1)
  123. self.__increment(node,True)
  124. self.__keyMap[key] = node
  125. def __increment(self, node, is_new_node=False):
  126. """
  127. 更新节点的访问频率
  128. Args:
  129. node:要更新的节点
  130. is_new_node:是否是新节点,新插入的节点和非新插入节点更新逻辑不同
  131. """
  132. if is_new_node:
  133. self.__minFreq = 1
  134. self.__setDefaultLinkedList(node)
  135. else:
  136. self.__deleteNode(node)
  137. node.freq += 1
  138. self.__setDefaultLinkedList(node)
  139. if self.__minFreq not in self.__freqMap:
  140. self.__minFreq += 1
  141. def __setDefaultLinkedList(self, node):
  142. """
  143. 根据节点的频率,插入到对应的LinkedList中,如果LinkedList不存在则创建
  144. Args:
  145. node:将要插入到LinkedList的节点
  146. """
  147. if node.freq not in self.__freqMap:
  148. self.__freqMap[node.freq] = LinkedList()
  149. linkedList = self.__freqMap[node.freq]
  150. linkedList.insertFirst(node)
  151. def __deleteNode(self, node):
  152. """
  153. 删除指定的节点,如果节点删除后,对应的双链表为空,则从__freqMap中删除这个链表
  154. Args:
  155. node:将要删除的节点
  156. """
  157. if node.freq not in self.__freqMap:
  158. return
  159. linkedList = self.__freqMap[node.freq]
  160. freq = node.freq
  161. linkedList.delete(node)
  162. if linkedList.isEmpty():
  163. del self.__freqMap[freq]
  164. def __removeMinFreqElement(self):
  165. """
  166. 删除频率最低的元素,从__freqMap和__keyMap中都要删除这个节点,
  167. 如果节点删除后对应的链表为空,则要从__freqMap中删除这个链表
  168. """
  169. linkedList = self.__freqMap[self.__minFreq]
  170. node = linkedList.getLast()
  171. linkedList.delete(node)
  172. del self.__keyMap[node.key]
  173. if linkedList.isEmpty():
  174. del self.__freqMap[node.freq]
  175. if __name__ == '__main__':
  176. operation = eval(input())
  177. data = eval(input())
  178. cache = eval("{}({})".format(operation.pop(0), data.pop(0)[0]))
  179. output = []
  180. for i, j in zip(operation, data):
  181. if i == 'put':
  182. methodcaller('put', j[0], j[1])(cache)
  183. output.append(None)
  184. elif i == 'get':
  185. output.append(methodcaller('get', j[0])(cache))
  186. print(output)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/632320
推荐阅读
相关标签
  

闽ICP备14008679号