effiencies.py: priority.py: queue.py: terminalplot.py: lab6_effciencies.py: #---------------------------------------------------- # Lab 6, Exercise 2 - Queue efficiencies # # Author of supporting code: CMPUT 175 Team # Author
effiencies.py:
priority.py:
queue.py:
terminalplot.py:
lab6_effciencies.py:
#---------------------------------------------------- # Lab 6, Exercise 2 - Queue efficiencies # # Author of supporting code: CMPUT 175 Team # Author of dequeue_experiment(): #----------------------------------------------------
import random import time from queues import BoundedQueue from queues import CircularQueue from decimal import Decimal from terminalplot import plot2
def enqueue_experiment(queue_class , queue_size ): ''' This function will enqueue elements into Bounded and Circular queues and return them :param queue_class: The queue_class description that we want to declare the object for like BoundedQueue, CircularQueue :param queue_size: The size of the queue and the number of elements that we want to enter in queue :return: Bounded Queue Object, Circular Queue Object ''' # init the relevant objects queue = queue_class(queue_size)
# enqueue elements to max capacity of queue while not queue.is_full(): value = random.random() queue.enqueue(value)
return queue
def dequeue_experiment(queue): ''' This function will be responsible for dequeues the elements in the queue :param queue: (queue object) The queue object that we want to test on :return: (float) Returns the time of execution of the dequeue operation ''' time = 0.0 # the time to dequeue all the elements ##### START CODE HERE #####
##### END CODE HERE ###### return time
def avg_dequeue_experiment(queue_class, size, sample_size = 5): ''' This function is used to average over many runs for the dequeue experiment :param queue_class: (function-type) The typeof queue that we are using :param size: (int) Size of the queue to do experiment :param sample_size : (int) THe number of samples to be used for averaging :return: (float) return the average time ''' q_run_avg = 0 for i in range(sample_size): queue = enqueue_experiment(queue_class, size) q_run_avg += dequeue_experiment(queue)
return float(q_run_avg)/sample_size
def main(): # queue sizes that we will use for different experiments # queues_sizes = [10000, 20000 , 30000, 40000, 50000, 60000, 70000,80000, 90000, 100000] queues_sizes = [10000, 30000, 50000, 70000, 90000, 100000]
# the setup of the experiment bqueues = [] cqueues = [] for q in queues_sizes: # print("Done for Queue Size : {}".format(q)) bq = enqueue_experiment(BoundedQueue, q) cq = enqueue_experiment(CircularQueue,q) bqueues.append(bq) cqueues.append(cq)
# perform the dequeue experiment bounded_queue_times = [dequeue_experiment(q) for q in bqueues] circular_queue_times = [dequeue_experiment(q) for q in cqueues]
# print table of results for one run each (not averaged) print("Times for Bounded and Circular Queue without using Average") line = '-'*(13 + 14*len(queues_sizes)) line2 = str('-'*13 + '+')*(1 + len(queues_sizes)) print(line) print(str(" Queue Size | " + ' '.join(" {:
# plot the terminal graph try: print(''' Legend : '*' : Points of the Bounded Queue '#' : Points of Circular Queue '+' : Points where both coincide''')
plot2(queues_sizes, bounded_queue_times , circular_queue_times) except: print("Not able to print graph. Continuing .....")
# run experiment using averages avg_b_queue_times = [avg_dequeue_experiment(BoundedQueue, size) for size in queues_sizes] avg_c_queue_times = [avg_dequeue_experiment(CircularQueue, size) for size in queues_sizes]
# display table of averaged results (multiple runs for each data point) print("Times for Bounded and Circular Queue with Averaging") print(line) print(str(" Queue Size | " + ' '.join(" {:
try: # plot the graph print(''' Legend : '*' : Points of the Bounded Queue '#' : Points of Circular Queue '+' : Points where both coincide''')
plot2(queues_sizes, avg_b_queue_times, avg_c_queue_times) except: print("Not able to print graph. Continuing .....")
if __name__ == '__main__': # calculate total program run time start = time.time() main() end = time.time() print("The program took {} seconds to run".format(end - start))
Exercise 1: Complete the Bounded and Circular Queue Class Definitions, and Test 1. Download and save queues.py from eClass. This file contains partial implementations for the Bounded Queue and the Circular Queue, as discussed in the lectures. enqueue (item) - Complete this method for both types of queues. You may refer directly to the lecture slides on eClass. dequeue () - Complete this method for both types of queues. You may refer directly to the lecture slides on eClass. 2. Test your Bounded Queue and Circular Queue classes (especially the methods you have just written). To get you started, queues.py contains the skeleton code for a number of tests to check various aspects of the Bounded Queue's implementation. Uncomment and run/write the code for each test, one at a time, to check that you get the same sample output as below. Test 1: Complete the try statement. If the Bounded Queue's dequeue() method is correct, an exception should be raised when you attempt to dequeue from the empty queue, bq. Handle it by printing out the argument of the exception. Change the argument string in the Bounded Queue's dequeue() definition and rerun this test - is the new message displayed on the screen now? Test 2: Test the Bounded Queue's enqueue() method by trying to add 'bob' to bq. When printing the contents of bq to the screen, are print (bg) and print (str(bq)) the same? Does the method isEmpty return the expected result? Test 3: Run given code. When multiple items are added to the queue, does the queue store them in the correct order (test the repr() function)? Do the isFull() and size() methods give the expected results? Test 4: Write a try statement to attempt to add an item to the full bq. If the Bounded Queue's enqueue() method is correct, it should raise an exception. Handle that exception in the main() by printing out the exception's argument. Test 5: Run given code. Can an item be removed from a full bounded queue? Does the dequeue() method return the expected item, and are the contents of bq updated? Test 6: Run given code. Test the capacity method. How is capacity different from size? Test 7: Try to access the private capacity attribute outside of the Bounded Queue class definition (i.e. in the main). What happens? Does the same thing happen if you try to access a non-private attribute outside of its class definition? Sample Output: My bounded queue is: Max=3 Is my bounded queue empty? True Try to dequeue an empty bounded queue... Error: Queue is empty bob bob Is my bounded queue empty? False bob eva paul Max=3 Is my bounded queue full? True There are 3 elements in my bounded queue. - -- - - - -- - - - -- - - Try to enqueue a full bounded queue... Error: Queue is full -- eva paul Max=3 bob was first in the bounded queue: eva paul There are 2 elements in my bounded queue. --- -- Total capacity is: 3 **IMPORTANT NOTE** In Exercises 2 and 3, you are provided with a large amount of code that has been written by someone else. You do not have to understand all of the implementation details of this code. However, you are responsible for understanding the general purpose of this code and how to use the functions we have provided. Prepare for your lab ahead of time by reviewing the provided code (pay attention to docstrings and other comments), and be ready to ask your TA questions about any parts you do not understand. Exercise 2: Compare the Time Efficiency of Bounded and Circular Queues In this task, you will compare the runtimes of the dequeue() methods in the Bounded Queue and the Circular Queue. In the Bounded Queue, the dequeue method removes the item at the front of the queue, and then shifts the remaining items in the list to the left (i.e. to fill in the hole created by removing that first item). For a Bounded Queue containing n items, what is the big-O time efficiency of the dequeue? In the Circular Queue, you just shift the head index when you dequeue an item - no shifting of the actual data elements is required. For a Circular Queue containing n items, what is the big-time efficiency of the dequeue? Considering your answers to the above two questions, which queue's dequeue do you predict will run faster? 1. Download and save lab6 efficiency.py and terminalplot.py. (Save in the same folder as your queue.py from Exercise 1.) In this file, both your Bounded and Circular Queues have been imported from queues.py. This file also contains 4 function definitions: 3 have already been completed for you (enqueue_experiment, average_de queue_experiment, and main). Read through the comments of those 3 functions to understand what they are doing. 2. Complete the function dequeue experiment (queue) so that it removes the first item in the queue, and continues to do so until that queue is empty. Note that the queue is passed in as an input to the function - so you do NOT have to create it or fill it with data in this function. Use a function from either the time or timeit modules to measure how long it takes to dequeue all of the items in the queue, and return that time measurement. Hint: there is an example of how to use time.time () at the bottom of lab6_efficiency.py. The time module returns times in seconds. import time start = time.time() # The statement(s) that you want to test end = time.time() time_interval = end - start 3. Run lab6_efficiency. (This may take some time to run.) This will run a number of experiments, measuring the time it takes to dequeue all items from Bounded and Circular Queues of increasing capacities. These times will be printed in a table for you to view. The data should also be plotted for you, with time on the y-axis, and n on the x-axis (where n is the number of dequeues made). If a plot is not displayed (i.e. if you see a message that says Not able to print graph. Continuing..."), plot the data from the table using a spreadsheet program. You can run more experiments with larger queue capacities to get more values for your graph, but keep in mind that doing so will increase the runtime of the overall program. Which has a more efficient dequeue method: the Bounded Queue, or the Circular Queue? Exercise 3: Using High and Low Priority Queues: Background information: Computing devices like laptops and smartphones may have multiple computing cores, which allow us to run multiple programs at once. But what happens when the number of programs that we want to run is more than the number of cores in our device? For example, what if we want to run & programs on a device with only 2 CPU cores? Job scheduling helps the device to run the most important programs first. Imagine that each program we want to run submits a job request to the operating system before it is actually run. Those jobs are stored in either a high-priority queue or a low-priority queue, depending on how important the program is. For example, processes that are fundamental to how the device operates (e.g. displaying things to the screen, dealing with system input and output) have a higher priority than user-installed applications (e.g. web browsers, music playing app, calculator app). At any given time, jobs waiting in the high-priority queue will be executed first, in the order that they were requested in. If there are no high-priority jobs waiting to be executed, then the jobs in the low-priority queue can be executed. Problem: 1. Download lab6_priority.py from eClass, and save in the same folder as your other lab files. This file contains a Job class definition, as well as two functions that have already been completed for you (get_job (), and process_complete()). Read the comments for this code to understand what it does. 2. Add code to the main () function in this file so that every time a new job is created i.e. every time get_job() is called), that job object is enqueued to the appropriate queue: high_priority_queue or low_priority_queue. Hint: use the Job's high priority method to check if a job is high-priority (True) or low- priority (False). Notice that get job() may also return no job (None) which will NOT go into either queue, so that must be checked for as well. 3. Complete the main() function so that whenever a process has finished (indicated when process complete() returns True), a new process is started by dequeuing a job from the appropriate queue. i.e. If there is at least one job in the high-priority queue, it should be dequeued and assigned to the current job variable. However, if the high-priority queue is empty and there is at least one job in the low-priority queue, then it should be dequeued and assigned to the current job variable. If a job has been successfully dequeued from either queue, the process_running variable should be set to True. Sample Output (your output may differ since the jobs are generated randomly): # # # # # # # # RUN : 1 # # # # # # # # Job [USER] Music generated [PROCESSOR] Busy Jobs waiting in High Priority Queue :0 Jobs waiting in Low Priority Queue :0 # # # # # # # # RUN : 2 ## # # # # # # Job [OS] Display generated [PROCESSOR] Busy Jobs waiting in High Priority Queue :1 Jobs waiting in Low Priority Queue :0 [PROCESSOR] Busy Jobs waiting in High Priority Queue :1 Jobs waiting in Low Priority Queue :0 #### #### RUN : 3 ******** Job [USER] Browser generated JOB COMPLETED ID Process Name Priority : 142 : [USER] Music LOW [PROCESSOR] Busy Jobs waiting in High Priority Queue :0 Jobs waiting in Low Priority Queue :1 ### ### ## RUN : 4 # # # # # # # # Job [USER] Browser generated [PROCESSOR] Busy Jobs waiting in High Priority Queue :0 Jobs waiting in Low Priority Queue : 2 ######## RUN : 5 ######## Job [OS] File Read generated JOB COMPLETED ID 329 Process Name Priority : [OS] Display : HIGH [PROCESSOR] Busy Jobs waiting in High Priority Queue :0 Jobs waiting in Low Priority Queue :2 #*****## RUN : 6 ######## Job [USER] Calculator generated JOB COMPLETED ID : 167 Process Name : [OS] File Read Priority : HIGH [PROCESSOR] Busy Jobs waiting in High Priority Queue :0 Jobs waiting in Low Priority Queue :2 ######## RUN : 7 ## # # # # # # Job [USER) Music generated [PROCESSOR] Busy Jobs waiting in High Priority Queue :0 Jobs waiting in Low Priority Queue :3 #*****## RUN : 8 ######## Job [OS] File Read generated JOB COMPLETED ID Process Name Priority : 486 : [USER) Browser LOW [PROCESSOR] Busy Jobs waiting in High Priority Queue :0 Jobs waiting in Low Priority Queue :3 ######## RUN : 9 ######## Job [USER) Browser generated [PROCESSOR] Busy Jobs waiting in High Priority Queue :0 Jobs waiting in Low Priority Queue : 4 #### #### RUN : 10 ######## Job [USER) Calculator generated [PROCESSOR] Busy Jobs waiting in High Priority Queue :0 Jobs waiting in Low Priority Queue : 5 Lab 6 - Queues.pdf lab6_efficiencies.py lab6_priority.py queues.py terminalplot.py # Lab 6, Exercise 2 - Queue efficiencies # Author of supporting code: CMPUT 175 Team # Author of dequeue_experiment(): #--- import random import time from queues import BoundedQueue from queues import CircularQueue from decimal import Decimal from terminalplot import plot2 def enqueue_experiment (queue_class , queue_size): This function will enqueue elements into Bounded and Circular queues and return them param queue_class: The queue_class description that we want to declare the object for like BoundedQueue, CircularQueue :param queue_size: The size of the queue and the number of elements that we want to enter in queue :return: Bounded Queue Object, Circular Queue Object # init the relevant objects queue = queue_class(queue_size) # enqueue elements to max capacity of queue while not queue. is_fullo: value = random.random() queue. enqueue(value) return queue def dequeue_experiment(queue): This function will be responsible for dequeues the elements in the queue :param queue: (queue object) The queue object that we want to test on :return: (float) Returns the time of execution of the dequeue operation time = 0.0 # the time to dequeue all the elements ##### START CODE HERE ##### ##### END CODE HERE ###### return time def avg_dequeue_experiment(queue_class, size, sample_size = 5): This function is used to average over many runs for the dequeue experiment :param queue_class: (function-type) The typeof queue that we are using :param size: (int) Size of the queue to do experiment :param sample_size : (int) The number of samples to be used for averaging :return: (float) return the average time q_run_avg = 0 for i in range(sample_size): queue = enqueue_experiment(queue_class, size) q_run_avg += dequeue_experiment(queue) return float(q_run_avg)/sample_size def main(): # queue sizes that we will use for different experiments # queues_sizes = [10000, 20000, 30000, 40000, 50000, 60000, 70000, 80000, queues_sizes = [10000, 30000, 50000, 70000, 90000, 100000] 90000, 100000] # the setup of the experiment bqueues = [] cqueues = [] for q in queues_sizes: # print("Done for Queue Size : {}".format(a)) bq = enqueue_experiment(BoundedQueue, q) cq = enqueue_experiment(CircularQueue, q) bqueues.append(ba) cqueues.append(ca) # perform the dequeue experiment bounded_queue_times = [dequeue_experiment(q) for q in bqueues] circular-queue_times = [dequeue_experiment(q) for q in cqueues] # print table of results for one run each (not averaged) print("Times for Bounded and Circular Queue without using Average") line = '-'*(13 + 14*len(queues_sizes)) line2 = str('-'*13 + '+')*(1 + len(queues_sizes)) print(line) print(str(" Queue Size | "+''.join(" {:= 0, ('Error: Illegal capacity: %d' % (capacity)) self.__items = [] # init the list / queue as empty self.--capacity = capacity # Adds a new item to the back of the queue, and returns nothing: def enqueue(self, item): Enqueue the element to the back of the queue :param item: the element to be enqueued :return: No returns #### START CODE HERE ##### Remember to check the conditions pass ##### END CODE HERE ###### # Removes and returns the front-most item in the queue. # Returns nothing if the queue is empty. def dequeue(self): Dequeue the element from the front of the queue and return it :return: The object that was dequeued ##### START CODE HERE ##### 1. remember to check the conditions 2. return the appropriate value pass ##### END CODE HERE ###### # Returns the front-most item in the queue, and DOES NOT change the queue. def peek(self): if len(self.__items) = 0, ('Error: Illegal capacity: %d' % (capacity)) # Initialize private attributes self.__items = [] self.__capacity = capacity self.__count=0 self.__head=0 self.__tail=0 # Allocate space for the circular queue for i in range(self.--capacity): self.__items.append(None) # Adds a new item to the back of the queue, and returns nothing: def enqueue(self, item): This function enqueues the item into the back of the queue :param item: The item to be queued :return: No returns ##### START CODE HERE ##### Remember to check the proper conditions pass ##### END CODE HERE ###### # Removes and returns the front-most item in the queue. # Returns nothing if the queue is empty. def dequeue(self): Dequeue the the element from the front of the queue and return the value :return: Returns the object that is dequeued ##### START CODE HERE ##### Remember to check the proper conditions (some hints) 1. get item at the head of queue 2. remove the item from the head of queue 3. decrease stored size of queue 4. Shift the head 5. return the item pass ##### END CODE HERE ###### # Returns the front-most item in the queue, and DOES NOT change the queue. def peek(self): if self.__count == 0: raise Exception('Error: Queue is empty') return self.__items[self.__head] # Returns True if the queue is empty, and False otherwise: def is_empty(self): return self.__count == 0 # Returns True if the queue is full, and False otherwise: def is_full(self): return self.__count == self._capacity # Returns the number of items in the queue: def size(self): return self.__count # Returns the number of items in the queue: def size(self): return self.__count # Returns the capacity of the queue: def capacity(self): return self.__capacity # Removes all items from the queue, and sets the size to 0 # clear() should not change the capacity def clear(self): self.__items = [] self.__count = 0 self.__head = 0 self.__tail = 0 # Returns a string representation of the queue: def __str__(self): str_exp = "]" i = self.__head for j in range(self.__count): str_exp += str(self.__items[i]) + " " i = (i+1) % self.__capacity return str_exp + "]". # Returns a string representation of the object CircularQueue def __repr__(self): return str(self.__items) + " H= " + str(self.__head) + " T="+str(self.--tail) + " (" +str(self.__count)+"/"+str(self.__capacity)+")" def main(): # Test bounded queue creation bq=BoundedQueue(3) print("My bounded queue is:", bq) print(repr(ba)) print("Is my bounded queue empty?", bq.isEmpty()) print('--- print('---------------------------------- # 1. To Do # Test when we try to dequeue from an EMPTY queue try: # To Do: Write your own test except Exception as dequeueError: # To Do: Write a way to handle it print ------------') # 2. To Do # Test adding one element to queue # Your test code goes here... print(ba) print(str(ba)) print("Is my bounded queue empty?", bq.isEmpty()) print('-- ----------- # 3. Uncomment and run # Test adding more elements to queue bq.enqueue("eva") bq.enqueue("paul") print(repr(ba)) print("Is my bounded queue full?", bq.isFull()) print("There are", bq.size(), "elements in my bounded queue.") print('---- -----------" # 4. To Do # Test trying to add an element to a FULL queue # Your test code goes here...hint: look at dequeuing from EMPTY queue print('----- # 5. Uncomment and run # Test removing element from full queue item = bq.dequeue() print(repr(ba)) print(item, "was first in the bounded queue:", bq) print("There are", bq.size(), "elements in my bounded queue.") print(' ----------------------------------') # 6. Uncomment and run # Test capacity of queue print("Total capacity is:", bq.capacity()) # 6. Uncomment and run # Test capacity of queue print("Total capacity is:", bq.capacity()) # 7. To Do: Uncomment print statements, one at a time # Can we just access private capacity attribute directly outside of Class definition? #print(bq.capacity) #print(bq.-_capacity) if __name__ == '__main__': maino Base code from here : https://github.com/kressi/terminalplot/blob/master/terminalplot/terminalplot.py #import fcntl import os #import termios import struct def plot_multiple(x1, yi,y2 , rows=None, columns=None): The first y1 will be '*' and the second will be '#' x, y list of values on x- and y-axis plot those values within canvas size (rows and columns) if not rows or not columns: rows, columns = get_terminal_size() # these might not be required arows = rows + 2 acols = columns + 4 # offset for caption rows -= 4 # Scale points such that they fit on canvas x_scaled = xscale(x, columns) y1_scaled, y2_scaled = yscale(y1,y2, rows) print(x_scaled) print(y1_scaled) print(y2_scaled) # Create empty canvas canvas = [['' for - in range(columns)] for - in range(rows)] # We can trry to print the axes # canvas[columns-1][0] = '0' # for i in range(columns-4,0): # canvas[1][i] = '-' # for i in range(1, rows): # canvas[i][4] = 'T' # Add scaled points to canvas for first plot for ix, iy in zip(x_scaled, y1_scaled): canvas[rows - iy - 1][ix] = '*' # print for the second plot for ix, iy in zip(x_scaled, y2_scaled): if canvas[rows - iy - 1][ix] == '*': canvas[rows - iy - 1][ix] = '#' else: canvas[rows - iy - 1][ix] = '+' # testing # canvas[0][0] = 'O'. # canvas[0][columns - 1] = '1' # canvas[rows - 1][0] = '2' # canvas[rows - 1][columns - 1] = '3' # we can replace the common point with another type of label # Print rows of canvas for row in [''.join(row) for row in canvas]: print(row) # Print scale print("'.join( [ ' Min x: ', str(min(x), Max x: ', str(max(x)), # 'Min y: ', str(min(y)), # ' Max y: ', str(max(y)) Min y: ', str(min(min(yi), min(y2))), Max y: ', str(max(max(y1), max(y2))) ])) def plot_multiple2(x1, yi, y2, rows=None, columns=None): Trying to print the axis as well The first y1 will be '*' and the second will be '#' x, y list of values on x- and y-axis plot those values within canvas size (rows and columns) if not rows or not columns : rows, columns = get_terminal_size() # offset for caption rows -= 4 # these might not be required arows = rows + 2 acols = columns + 4 # Scale points such that they fit on canvas X_scaled = xscale(x, columns - 4) y1_scaled, y2_scaled = yscale(y1, y2, rows) # print(x_scaled) # print(y1_scaled) # print(y2_scaled) # Create empty canvas canvas = [['' for - in range(columns)] for - in range(arows)] # We can trry to print the axes # canvas[columns-1][0] = '0' # for i in range(columns-4,0): # canvas[1][i] = '_' # for i in range(1, rows): canvas[i][4] = 'I' # Add scaled points to canvas for first plot for ix, iy in zip(x_scaled, y1_scaled): canvas[rows - iy - 1][ix + 4] = '*' # i = 0 for ix, iy in zip(x_scaled, y1_scaled): # if ix = 0, ('Error: Illegal capacity: %d' % (capacity)) self.__items = [] # init the list / queue as empty self.--capacity = capacity # Adds a new item to the back of the queue, and returns nothing: def enqueue(self, item): Enqueue the element to the back of the queue :param item: the element to be enqueued :return: No returns #### START CODE HERE ##### Remember to check the conditions pass ##### END CODE HERE ###### # Removes and returns the front-most item in the queue. # Returns nothing if the queue is empty. def dequeue(self): Dequeue the element from the front of the queue and return it :return: The object that was dequeued ##### START CODE HERE ##### 1. remember to check the conditions 2. return the appropriate value pass ##### END CODE HERE ###### # Returns the front-most item in the queue, and DOES NOT change the queue. def peek(self): if len(self.__items) = 0, ('Error: Illegal capacity: %d' % (capacity)) # Initialize private attributes self.__items = [] self.__capacity = capacity self.__count=0 self.__head=0 self.__tail=0 # Allocate space for the circular queue for i in range(self.--capacity): self.__items.append(None) # Adds a new item to the back of the queue, and returns nothing: def enqueue(self, item): This function enqueues the item into the back of the queue :param item: The item to be queued :return: No returns ##### START CODE HERE ##### Remember to check the proper conditions pass ##### END CODE HERE ###### # Removes and returns the front-most item in the queue. # Returns nothing if the queue is empty. def dequeue(self): Dequeue the the element from the front of the queue and return the value :return: Returns the object that is dequeued ##### START CODE HERE ##### Remember to check the proper conditions (some hints) 1. get item at the head of queue 2. remove the item from the head of queue 3. decrease stored size of queue 4. Shift the head 5. return the item pass ##### END CODE HERE ###### # Returns the front-most item in the queue, and DOES NOT change the queue. def peek(self): if self.__count == 0: raise Exception('Error: Queue is empty') return self.__items[self.__head] # Returns True if the queue is empty, and False otherwise: def is_empty(self): return self.__count == 0 # Returns True if the queue is full, and False otherwise: def is_full(self): return self.__count == self._capacity # Returns the number of items in the queue: def size(self): return self.__count # Returns the number of items in the queue: def size(self): return self.__count # Returns the capacity of the queue: def capacity(self): return self.__capacity # Removes all items from the queue, and sets the size to 0 # clear() should not change the capacity def clear(self): self.__items = [] self.__count = 0 self.__head = 0 self.__tail = 0 # Returns a string representation of the queue: def __str__(self): str_exp = "]" i = self.__head for j in range(self.__count): str_exp += str(self.__items[i]) + " " i = (i+1) % self.__capacity return str_exp + "]". # Returns a string representation of the object CirculStep by Step Solution
There are 3 Steps involved in it
Step: 1
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started