class CircularQueueArray:
    #constructor, Time O(1), Space O(1)
    def __init__(self, size):
        self.maxSize = size
        self.queue = [None] * size
        self.frontIndex = self.rearIndex = -1
        self.length = 0

    #Add at the rear, Time O(1), Space O(1)
    def enqueue(self, value):
        if self.is_full(): #full
            print("The circular queue is full, cannot enqueue " + str(value))
            return
        if (self.frontIndex == -1): #empty
            self.frontIndex = 0
        self.rearIndex = (self.rearIndex + 1) % self.maxSize
        self.queue[self.rearIndex] = value
        self.length += 1

    # Remove from the front, Time O(1), Space O(1)
    def dequeue(self):
        if self.is_empty():
            print("The circular queue is empty, cannot dequeue")
            return
        item = self.queue[self.frontIndex]
        if (self.frontIndex == self.rearIndex): #one item left
            self.frontIndex = -1
            self.rearIndex = -1
        else:           
            self.frontIndex = (self.frontIndex + 1) % self.maxSize
        self.length -= 1
        return item

    #Return front value, Time O(1), Space O(1)
    def peek(self):
        if self.is_empty():
            print("The circular queue is empty, cannot dequeue")
            return
        return self.queue[self.frontIndex]

    #Print all, Time O(n), Space O(1), n is number of items in queue
    def print(self):
        if self.is_empty():
            print("The circular queue is empty")
            return
        i = self.frontIndex   
        while i != self.rearIndex:
            print(str(self.queue[i]) , end = " ")
            i = (i + 1) % self.maxSize
        print(self.queue[i])      
        
	#return number of items in queue, Time O(1), Space O(1)
    def size(self):
        return self.length
	
    #Check full, Time O(1), Space O(1)
    def is_full(self):
        return (self.rearIndex + 1) % self.maxSize == self.frontIndex
    
    #Check empty, Time O(1), Space O(1)
    def is_empty(self):
        return self.frontIndex == -1

if __name__ == "__main__":
#Initialize, enqueue, size
    queue = CircularQueueArray(5)
    queue.enqueue(10)
    queue.enqueue(20)
    queue.enqueue(30)
    queue.enqueue(80)
    queue.enqueue(54)
    queue.enqueue(60)
    queue.print()
    print("size: " + str(queue.size()))
    print("peek: " + str(queue.peek()))  

    #Dequeue 
    queue.dequeue()  
    queue.dequeue()  
    queue.print()
    print("size: " + str(queue.size())) 
    print("peek: " + str(queue.peek()))  

    #Enqueue again
    queue.enqueue(60)
    queue.print()
    print("size: " + str(queue.size()))
    print("peek: " + str(queue.peek()))   