diff --git a/tests/test_utils.py b/tests/test_utils.py index 76e0421b3..f8d7035d3 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,6 +1,6 @@ import pytest from utils import * # noqa - +import random def test_removeall_list(): assert removeall(4, []) == [] @@ -177,6 +177,53 @@ def test_expr(): assert (expr('GP(x, z) <== P(x, y) & P(y, z)') == Expr('<==', GP(x, z), P(x, y) & P(y, z))) +def test_FIFOQueue() : + # Create an object + queue = FIFOQueue() + # Generate an array of number to be used for testing + test_data = [ random.choice(range(100)) for i in range(100) ] + # Index of the element to be added in the queue + front_head = 0 + # Index of the element to be removed from the queue + back_head = 0 + while front_head < 100 or back_head < 100 : + if front_head == 100 : # only possible to remove + # check for pop and append method + assert queue.pop() == test_data[back_head] + back_head += 1 + elif back_head == front_head : # only possible to push element into queue + queue.append(test_data[front_head]) + front_head += 1 + # else do it in a random manner + elif random.random() < 0.5 : + assert queue.pop() == test_data[back_head] + back_head += 1 + else : + queue.append(test_data[front_head]) + front_head += 1 + # check for __len__ method + assert len(queue) == front_head - back_head + # chek for __contains__ method + if front_head - back_head > 0 : + assert random.choice(test_data[back_head:front_head]) in queue + + # check extend method + test_data1 = [ random.choice(range(100)) for i in range(50) ] + test_data2 = [ random.choice(range(100)) for i in range(50) ] + # append elements of test data 1 + queue.extend(test_data1) + # append elements of test data 2 + queue.extend(test_data2) + # reset front_head + front_head = 0 + + while front_head < 50 : + assert test_data1[front_head] == queue.pop() + front_head += 1 + + while front_head < 100 : + assert test_data2[front_head - 50] == queue.pop() + front_head += 1 if __name__ == '__main__': pytest.main() diff --git a/utils.py b/utils.py index ed44f1e9e..5cd18a632 100644 --- a/utils.py +++ b/utils.py @@ -571,7 +571,7 @@ def __missing__(self, key): # ______________________________________________________________________________ # Queues: Stack, FIFOQueue, PriorityQueue -# TODO: Possibly use queue.Queue, queue.PriorityQueue +# TODO: queue.PriorityQueue # TODO: Priority queues may not belong here -- see treatment in search.py @@ -607,29 +607,32 @@ class FIFOQueue(Queue): """A First-In-First-Out Queue.""" - def __init__(self): - self.A = [] - self.start = 0 + def __init__(self, maxlen=None, items=[]): + self.queue = collections.deque(items, maxlen) def append(self, item): - self.A.append(item) - - def __len__(self): - return len(self.A) - self.start + if not self.queue.maxlen or len(self.queue) < self.queue.maxlen: + self.queue.append(item) + else: + raise Exception('FIFOQueue is full') def extend(self, items): - self.A.extend(items) + if not self.queue.maxlen or len(self.queue) + len(items) <= self.queue.maxlen: + self.queue.extend(items) + else: + raise Exception('FIFOQueue max length exceeded') def pop(self): - e = self.A[self.start] - self.start += 1 - if self.start > 5 and self.start > len(self.A) / 2: - self.A = self.A[self.start:] - self.start = 0 - return e + if len(self.queue) > 0: + return self.queue.popleft() + else : + raise Exception('FIFOQueue is empty') + + def __len__(self): + return len(self.queue) def __contains__(self, item): - return item in self.A[self.start:] + return item in self.queue class PriorityQueue(Queue):