__author__ = 'keithd' # A few classes for handling lists of items in different ways. # *************** CHAIN ******************* # The base class class Chain(): _max_size = 100 # A class variable # **** Class Methods @staticmethod # a "decorator" just to remind us that this is a class method and hence has no "self". def size_limit(): return Chain._max_size def make(items=[]): # Also a class method (without the @staticmethod decorator) return Chain(items) # **** Instance Methods def __init__(self,init_links=[]): self.links = init_links.copy() def get_links(self): return self.links def pp(self): for index in range(len(self.links)): print(index, " : ", self.links[index]) def len(self): return len(self.links) def add(self,item): if self.len() < Chain._max_size: self.links.append(item) # Always adds to the end of the chain. def pop(self): return self.links.pop() # Remove and return the LAST item of the chain def join(self,chain2): if self.len() + chain2.len() <= Chain._max_size: self.links.extend(chain2.get_links()) def copy(self): return type(self)(self.links) # Should work for Chain or any of the subclasses # Operator overloading (==,<,+...) def __eq__(self,c2): return type(self) == type(c2) and self.links == c2.links def __gt__(self,c2): return self.links > c2.links def __str__(self): return str(self.links) # same as self.links__str__() def __repr__(self): return str(type(self)) + " links: " + str(self) def __add__(self,c2): return Chain(self.links + c2.links) # *************** STACK ***************************** # Push and pop from same location: the END of self.links. Otherwise, no access to any other links. class Stack(Chain): def __init__(self,init_links=[]): Chain.__init__(self,init_links) # Use superclass init def push(self,item): self.add(item) # *************** QUEUE ***************************** # Push to START of self.links and pop from END. Otherwise, no access to any other links. class Queue(Chain): def __init__(self,init_links=[]): Chain.__init__(self,init_links) def push(self,item): if self.len() < Queue._max_size: # Note: the class variable is inherited by the subclass self.links.insert(0,item) # NOTE: For really efficient queue implementation, use the python "collections" module: # "from collections import deque" # *************** SERIES ***************************** # This allows access and modification of ANY link in the chain. class Series(Chain): def __init__(self,init_links=[]): Chain.__init__(self,init_links) self.currloc = -1 # Keep track of current location in the series def get_currloc(self): return self.currloc def insert(self,index,item): if self.len() < self._max_size: # Note: class variable also accessible via the object itself self.links.insert(index,item) def delete(self,index): if index < self.len(): del self.links[index] # Using python's del(ete) statement def update(self,index,item): self.links[index] = item def next(self): self.currloc += 1 return self.links[self.currloc] if self.currloc < self.len() else None # ************** RING ******************** # A series that, when iterated, simply loops back on itself class Ring(Series): def __init__(self,init_links=[]): Series.__init__(self,init_links) def next(self): if self.links: self.currloc = (self.currloc + 1) % self.len() # Use modulo to loop back to start of links from end of links return self.links[self.currloc]