#!/usr/bin/python3 from heapq import heappush, heappop import itertools import math # A simple priority queue based on the heapq class. class PQueue(object): REMOVED = '' # placeholder for a removed task def __init__(self): self.pq = [] # list of entries arranged in a heap self.entry_finder = {} # mapping of tasks to entries self.counter = itertools.count() # unique sequence count self.size = 0 def push(self, task, priority=0): 'Add a new task or update the priority of an existing task' if task in self.entry_finder: self.remove(task) else: self.size += 1 entry = [priority, next(self.counter), task] self.entry_finder[task] = entry heappush(self.pq, entry) def remove(self, task): 'Mark an existing task as REMOVED. Raise KeyError if not found.' entry = self.entry_finder.pop(task) entry[-1] = self.REMOVED self.size -= 1 def pop(self): 'Remove and return the lowest priority task. Raise KeyError if empty.' while self.pq: priority, count, task = heappop(self.pq) if task is not self.REMOVED: del self.entry_finder[task] self.size -= 1 return task return None def __len__(self): return self.size # Return [n]th line in [text]. def get_line(text, n): lines = text.split('\n') if n >= 0 and n < len(lines): return lines[n] return None # Indent each line in [text] by [indent] spaces. def indent(text, indent=2): return '\n'.join([' '*indent+line for line in text.split('\n')]) # Average in a list. def avg(l): return sum(l)/len(l) # Logistic function. def logistic(x, L=1, k=1, x_0=0): return L/(1+math.exp(-k*(x-x_0)))