class CQ_Error(Exception):
    def __init__(self,expression,message):
        self.expression = expression
        self.message = message
class CircularQ():        
    import numpy as np
    #populate the array with None

    def __init__(self,s):
        # added an if statement to check if the s argument passed is an integer
        if type(s) == int:
            self.sz = s        # array size, it should be 7
            self.cq = self.np.ndarray(self.sz)
            for i in range(0,self.sz):
                self.cq[i] = 0
            
            ## Initially the value of both head and tail should be -1. 
            self.head = -1
            self.tail = -1
        else:
            raise Exception('Circular Queue error: queue accepts integers only.')
           
    def enqueue(self,item):   
        ## check for overflow 
        if (self.head + 1) % self.sz == self.head:
            print(" Queue is Full!\n")
             
        ## condition for empty queue, if empty increase head and tail by 1 and add item
        elif self.head == -1:
            self.head = 0
            self.tail = 0
            self.cq[self.tail] = item
        
        ## if not empty then move tail to next position and add item
        else:
            # next position of tail
            self.adjTail()
            self.cq[self.tail] = item
       
    def printQueue(self):
        ## condition for empty queue
        if self.head == -1:
            print ("Queue is Empty")
 
        elif self.tail >= self.head:
            print("Elements in the circular queue are:",
                                              end = " ")
            for i in range(self.head, self.tail + 1):
                print(self.cq[i], end = " ")
            print ()
 
        else:
            print ("Elements in Circular Queue are:",
                                           end = " ")
            for i in range(self.head, self.sz):
                print(self.cq[i], end = " ")
            for i in range(0, self.tail + 1):
                print(self.cq[i], end = " ")
            print ()
 
        if (self.tail + 1) % self.sz == self.head:
            print("Queue is Full!")
   
    def adjHead(self):
        self.head = self.head+1
       
    def adjTail(self):
        ## Divide tail+1 with sz
        self.tail = (self.tail+1) % self.sz
   
    def dequeue(self):
        ## condition for empty queue
        if (self.head == -1): 
            print ("Queue is Empty\n")
             
        ## condition for only one element
        elif self.head == self.tail:
            temp=self.cq[self.head]
            self.head = -1
            self.tail = -1
            return temp
        else:
            temp = self.cq[self.head]
            self.head = (self.head + 1) % self.sz
            return temp
   
    def is_Empty(self) -> bool:
        rc = False
        if self.tail == self.head:
            print("Circular queue is EMPTY!")
            rc = True
        return rc
    def printtail(self):
        print('\nTail: ', self.tail)
    def printhead(self):
        print('Head: ', self.head)


## Take input from the user

while True:
    n = 1
    print(n,"=========================================================.") 
    n+=1
    print("1. Insert item into the queue")
    print("2. Delete item from the queue")
    choice = float(input("Enter your choice(0 for stop): "))
    
    if choice == 1:
        queue_size = int(input("Enter the queue size: "))
        c1 = CircularQ(queue_size)  #is taking the size and creating an array of that size

        for i in range(queue_size):
            item = int(input("Enter item: "))
            c1.enqueue(item)

    elif choice == 2:
        c1.dequeue()

    elif choice == 0:
        break

    else:
        print("Invalid choice!")

    c1.printQueue()
    c1.printtail()
    c1.printhead()