#coding: utf-8
#=======================================================================================[ T_QUEUE ]=======
class T_QUEUE:
  '''Klasa kolejki - struktury FIFO lub LILO. First Input First Output/ Last I Last O'''
  _DATA=[]									# Pojemnik na dane - zasadnicza kolejka.

#------------------------------------ INIT -------------------------------------------
#---============================[ __init__ ]==========================================[]
  def __init__(self,LEN=None):
    '''Inicjacja z ew. nax długością kolejki LEN.'''
    self._LEN=LEN								# Zapamiętuje ograniczenie długości. None - brak.
    self._DATA=[]								# Tworzy indywidualny pojemnik na dane.

#------------------------------------ OPER -------------------------------------------
#---============================[ APPEND ]==========================================[]
  def APPEND(self,I):
    '''Dopisuje element do kolejki. Jeśli jest przepełnienie zgłasza błąd.'''
    #self.BREAKif_isERROR("+")							# Przerywa jeśli kolejka jest pełna.
    self._DATA+=[I]								# Dodaje element na końcu kolejki (końcu listy).

#---============================[ SHIFT ]==========================================[]
  def  SHIFT(self):
    '''Pobiera element ze kolejki. Jeśli jest pusty - zgłasza błąd.'''
    #self.BREAKif_isERROR("-")							# Przerywa jeśli kolejka jest pusta.
    return self._DATA.pop(0)							# Pobiera i zwraca element z przodu kolejki (początku listy).


#------------------------------------ SIZE -------------------------------------------
#---============================[ size ]==========================================[]
  def size(self,FULL=False):
    '''Zwraca wielkość kolejki. Gdy FULL - zwraca krotke: (aktualna_wielkość,max_wielkość).'''
    RES=len(self._DATA)								# Ustala aktualną wielkość stoosu.
    if FULL: 									# Ma zwrócić i wartość aktualną i maksymalną.
      return (RES,self._LEN)							# Zwraca krotke z danymi.
    return RES									# Zwraca samą wielkość kolejki.

#---============================[ isEMPTY ]==========================================[]
  def isEMPTY(self):
    '''Zwraca .T.  jeśli kolejka jest pusta.'''
    return self.size()==0							# Zwraca .T. jeśli kolejka jest pusta - ma wielkość zero.

#---============================[ isFULL ]==========================================[]
  def isFULL(self):
    '''Zwraca .T.  jeśli kolejka jest pełna - ma już max ilość elementów.'''
    if _LEN==None: return False
    (S,M)=self.size(True)
    return S==M									# Zwraca .T. jeśli kolejka jest pełna - ma wielkość max.

#------------------------------------ ERRORS -------------------------------------------
#---============================[ BREAKif_isERROR ]==========================================[]
  def BREAKif_isERROR(self,DIR):
    '''Jeśli DIR="-" i koleja jest pusta zgłasza błąd "QUEUE is EMPTY".'''
    if DIR=="-" and self.isEMPTY():
      E='QUEUE is EMPTY'
      print(f'{E}!')
      raise Exception(E)
    if DIR=="+" and self.isFULL():
      E='QUEUE is FULL'
      print(f'{E}!')
      raise Exception(E)

#------------------------------------ SHOW -------------------------------------------
#---============================[ SHOW ]==========================================[]
  def SHOW(self):
    '''pokazuje w przyjazny sposób kolejkę.'''
    print('-'*40)
    for i in range(self.size()):
      print(f'> {self._DATA[i]:4d} <',sep=',',end='')
    print()
    print('='*40)
    print(f' QUEUE {"not" if not self.isEMPTY() else ""} is EMPTY')
    print(f' QUEUE {"not" if not self.isFULL() else ""} is FULL')


#---============================[ __name__ ]==========================================[]
if __name__=="__main__":
  QUEUE=T_QUEUE(5)
  QUEUE.SHOW()
  for i in range(6):
    try:
      print(f'APPEND({10*i})')
      QUEUE.APPEND(10*i)
    except Exception as E:
      print(f'ERROR: {E}')
    QUEUE.SHOW()
  print('.'*100)
  for i in range(4):
    try:
      Q=QUEUE.SHIFT()
      print(f'Przesunął z kolejki {Q}')
    except Exception as E:
      print(f'ERROR: {E}')
    QUEUE.SHOW()
    print(f'APPEND({2*Q})')
    QUEUE.APPEND(Q*2)
    QUEUE.SHOW()
  for i in range(6):
    try:
      Q=QUEUE.SHIFT()
      print(f'Przesunął z kolejki {Q}')
    except Exception as E:
      print(f'ERROR: {E}')
    QUEUE.SHOW()






