用于打印机任务的仿真:一段时间内,打印任务和打印机状态的模拟
构造三个对象:
(1)打印机:实现了打印机的打印速度、剩余打印时间、打印任务三个属性,以及是否闲置、开启一项新任务和打印三个方法
(2)打印任务:实现了任务的随机生成、任务量的生成、等待时间统计
(3)打印队列:实现了打印任务的入列和出列操作,从而完成了打印任务和打印机之间的交互
以时间(每秒)为单位,依次进行:1)是否生成新的打印任务;2)若生成新任务的话,入列;3)查看打印机状态;4)若打印机闲置,队列有任务的化出列进行打印;
5)打印机有任务打印;6)查看打印任务的完成情况,并视情重置打印机状态
import random
# 全局变量
PPM = 5 # page per minute, 打印机每分钟打印张数
TP = 21 # task page, 随机任务的张数上限
TF = 180 # task frequency, 平均每多少s随机生成一个任务
# 队列类
class Quene(object):
def __init__(self):
self.data = []
def __repr__(self):
return f"Quene({self.data})"
def enquene(self, value):
# 入队列
self.data.append(value)
def dequene(self):
# 出队列
if self.isEmpty():
raise IndexError("dequene from empty quene")
else:
return self.data.pop(0)
def __len__(self):
return len(self.data)
def isEmpty(self):
return len(self.data) == 0
def rotate(self,times):
# 队列的顺序翻转
for _ in range(times):
self.enquene(self.dequene())
class Printer(object):
def __init__(self, ppm):
self.ppm = ppm # 超参,每分钟打印速度
self.remaining_time = 0 # 剩余打印时间初始值
self.current_task = None # 当前任务
def tick(self):
# 以s为单位,打印
self.remaining_time -= 1
if self.remaining_time < 0:
self.current_task = None
def isBusy(self):
# 校验打印机是否在工作
if self.current_task:
return True
else:
return False
def start_task(self, task):
# 开启新的任务
self.current_task = task
self.remaining_time = task.get_pages() * 60 / self.ppm
class Task(object):
def __init__(self, time_stamp):
self.task_pages = random.randrange(1, TP)
self.time_stamp = time_stamp # 生成任务时生成时间戳,以统计等待时间
def get_time(self):
return self.time_stamp
def get_pages(self):
return self.task_pages
def wait_time(self, current_time): # 统计等待时间
return current_time - self.time_stamp
def simulate(total_time):
"""
仿真主程序
"""
printer = Printer(PPM)
printer_quene = Quene()
wait_time_list = [] # 所有需等待任务的等待时间列表
for t in range(total_time):
# 1. 根据随机数是否生成新任务,并加入队列
choice = random.randrange(1, TF + 1)
if choice == TF:
new_task = Task(t)
printer_quene.enquene(new_task)
# 2. 视情决定是否将任务进行打印
if not printer.isBusy() and not printer_quene.isEmpty():
dequene_task = printer_quene.dequene()
printer.start_task(dequene_task)
wait_time = dequene_task.wait_time(t)
wait_time_list.append(wait_time)
# 3. 视情进行打印
if printer.current_task:
printer.tick()
# 4. 统计等待时间
waiting_num = len(printer_quene)
average_wait_time = sum(wait_time_list) / len(wait_time_list)
print("{} tasks remain waiting, the average time of waiting is {}!".format(waiting_num, average_wait_time))
if __name__ == '__main__':
for i in range(10):
simulate(3600)