Question

In: Computer Science

Implement a Bag ADT using Dynamic Array structure as underlying data storage for Bag ADT. RESTRICTIONS:...

Implement a Bag ADT using Dynamic Array structure as underlying data storage for Bag ADT. 

RESTRICTIONS: Not allowed to use ANY built-in Python data structures and their methods. You must solve by importing the DynamicArray class and using class methods to write solution. Also not allowed to directly access any variables of the DynamicArray class (like self.size, self.capacity and self.data in part 1). All work must be done by only using class methods.

Below is the Bag ADT starter code and the Dynamic Array program. Basic testing below shows how the code might be used.

Bag Methods to implement:

add (self, value: object) -> None: This method adds a new element to the bag.remove()

remove (self, value: object) -> bool: This method removes any one element from the bag that matches the provided “value” object. Method returns True if some object was actually removed from the bag. Otherwise it returns False.

count (self, value: object) -> int: This method counts the number of elements in the bag that match the provided “value” object.

clear (self) -> None: This method clears the content of the bag.

size (self) -> int: This method returns the number of elements currently in the bag.

equal (self, second_bag: object) -> bool: This method compares the content of the bag with the content of the second bag provided by the user. Method returns True if the bags are equal (have the same number of elements and contain the same elements without regards to the order of elements). Otherwise it returns False. Empty bag is only considered equal to another empty bag. This method should not change the contents of either bag.

#Dynamic Array Code

class DynamicArrayException(Exception):
    """
    Custom exception class to be used by Dynamic Array
    DO NOT CHANGE THIS METHOD IN ANY WAY
    """
    pass


class DynamicArray:
    def __init__(self, start_array=None):
        """
        Initialize new dynamic array
        DO NOT CHANGE THIS METHOD IN ANY WAY
        """
        self.size = 0
        self.capacity = 4
        self.data = [None] * self.capacity

        # populate dynamic array with initial values (if provided)
        # before using this feature, implement append() method
        if start_array is not None:
            for value in start_array:
                self.append(value)

    def __str__(self) -> str:
        """
        Return content of dynamic array in human-readable form
        DO NOT CHANGE THIS METHOD IN ANY WAY
        """
        out = "DYN_ARR Size/Cap: "
        out += str(self.size) + "/"+ str(self.capacity)
        out += " " + str(self.data[:self.size])
        return out

    def resize(self, new_capacity: int) -> None:

        if (new_capacity == 0) or (new_capacity < self.size):
            return

        new_data = [None] * new_capacity

        for i in range(self.size):
            new_data[i] = self.data[i]

        self.capacity = new_capacity
        self.data     = new_data
        return

    def append(self, value: object) -> None:

        if self.is_full():
            self.resize(self.capacity * 2)

        self.data[self.size] = value
        self.size += 1

        return

    def insert_at_index(self, index: int, value: object) -> None:

        if (index < 0) or (index > self.size):
            raise DynamicArrayException

        if self.is_full():
            self.resize(self.size * 2)


        for current_index in range(self.size, index, -1):
            self.data[current_index] = self.data[current_index - 1]


        self.data[index] = value
        self.size       += 1

        return

    def get_at_index(self, index: int) -> object:

        if (index < 0) or (index > self.size - 1):
            raise DynamicArrayException

        return self.data[index]

    def remove_at_index(self, index: int) -> None:


        if (index < 0) or (index > self.size - 1):
            raise DynamicArrayException

        if (self.size < (0.25 * self.capacity)) and self.capacity > 10:
            if self.size < 5:
                self.resize(10)
            else:
                self.resize(self.size * 2)


        for i in range(index, self.size):
            if i == (self.size - 1):
                self.data[i] = None
            else:
                self.data[i] = self.data[i + 1]


        self.size -= 1

        return

    def is_empty(self) -> bool:
 
        return self.size == 0

    def length(self) -> int:

        return self.size

    def slice(self, start_index: int, quantity: int) -> object:


        if (start_index < 0) or (start_index > self.size - 1):
            raise DynamicArrayException

  
        if (quantity < 0) or (quantity > (self.size - start_index)):
            raise DynamicArrayException


        new_array = DynamicArray()


        for i in range(start_index, (start_index + quantity)):
            new_array.append(self.data[i])

        return new_array

    def reverse(self) -> None:
 

        if self.size <= 1:
            return


        front_index = 0
        back_index  = self.size - 1


        while front_index < (self.size / 2):

            front_val = self.get_at_index(front_index)
            back_val  = self.get_at_index(back_index)


            self.remove_at_index(front_index)
            self.insert_at_index(front_index, back_val)

            self.remove_at_index(back_index)
            if back_index == self.size:
                self.append(front_val)
            else:
                self.insert_at_index(back_index, front_val)


            front_index += 1
            back_index  -= 1

        return

    def sort(self) -> None:


        if self.size <= 1:
            return


        current_index = 1


        while current_index < self.size:

            comparison_index = current_index - 1
            sorting          = True


            while sorting:

                current_val = self.get_at_index(current_index)


                if current_val < self.get_at_index(comparison_index):
                    if comparison_index == 0:
                        self.remove_at_index(current_index)
                        self.insert_at_index(0, current_val)
                        sorting = False

                    else:
                        comparison_index -= 1

                else:
                    self.remove_at_index(current_index)
                    self.insert_at_index(comparison_index + 1, current_val)
                    sorting = False

            current_index += 1

        return

    def merge(self, another_list: object) -> None:
  
        # Iterate the given list values and append
        for i in range(another_list.length()):
            self.append(another_list.get_at_index(i))

        return

    def is_full(self) -> bool:

        if self.size == self.capacity:
            return True

        return False

#Bag Starter Code

from dynamic_array import *


class Bag:
    def __init__(self, start_bag=None):
        """
        Init new bag based on Dynamic Array
        DO NOT CHANGE THIS METHOD IN ANY WAY
        """
        self.da = DynamicArray()

        # populate bag with initial values (if provided)
        # before using this feature, implement add() method
        if start_bag is not None:
            for value in start_bag:
                self.add(value)

    def __str__(self) -> str:
        """
        Return content of bag in human-readable form
        DO NOT CHANGE THIS METHOD IN ANY WAY
        """
        out = "BAG: " + str(self.da.size) + " elements. "
        out += str(self.da.data[:self.da.size])
        return out

    def add(self, value: object) -> None:
        """
        TODO: Write this implementation
        """
        return

    def remove(self, value: object) -> bool:
        """
        TODO: Write this implementation
        """
        return False

    def count(self, value: object) -> int:
        """
        TODO: Write this implementation
        """
        return 0

    def clear(self) -> None:
        """
        TODO: Write this implementation
        """
        return

    def size(self) -> int:
        """
        TODO: Write this implementation
        """
        return 0

    def equal(self, second_bag: object) -> bool:
        """
        TODO: Write this implementation
        """
        return False

##Basic Testing

if __name__ == "__main__":
    pass

##Add Example Test:

bag = Bag()

print(bag)

values = [10, 20, 30, 10, 20, 30]

for value in values:

bag.add(value)

print(bag)

#Output:

#BAG: 0 elements. []

#BAG: 6 elements. [10, 20, 30, 10, 20, 30]

#########

##Remove Example Test:

bag = Bag([1, 2, 3, 1, 2, 3, 1, 2, 3])

print(bag)

print(bag.remove(7), bag)

print(bag.remove(3), bag)

print(bag.remove(3), bag)

print(bag.remove(3), bag)

print(bag.remove(3), bag)

#Output:

#BAG: 9 elements. [1, 2, 3, 1, 2, 3, 1, 2, 3]

#False BAG: 9 elements. [1, 2, 3, 1, 2, 3, 1, 2, 3]

#True BAG: 8 elements. [1, 2, 1, 2, 3, 1, 2, 3]

#True BAG: 7 elements. [1, 2, 1, 2, 1, 2, 3]

#True BAG: 6 elements. [1, 2, 1, 2, 1, 2]

#False BAG: 6 elements. [1, 2, 1, 2, 1, 2]

#########

#Count Example Testing:

bag = Bag([1, 2, 3, 1, 2, 2])

print(bag, bag.count(1), bag.count(2), bag.count(3), bag.count(4))

#Output:

#BAG: 6 elements. [1, 2, 3, 1, 2, 2] 2 3 1 0

#########

#Clear Example Testing:

bag = Bag([1, 2, 3, 1, 2, 3])

print(bag)

bag.clear()

print(bag)

#Output:

#BAG: 6 elements. [1, 2, 3, 1, 2, 3]

#BAG: 0 elements. []

#########

#Size Example Testing:

bag = Bag([10, 20, 30, 40])

print(bag.size(), bag.remove(30), bag.size())

bag.clear()

print(bag.size())

#Output:

#4 True 3

#0

#########

#Equal Example Testing:

bag1 = Bag([1, 2, 3, 4, 5, 6])

bag2 = Bag([6, 5, 4, 3, 2, 1])

bag3 = Bag([1, 2, 3, 4, 5])

bag_empty = Bag()

print(bag1, bag2, bag3, bag_empty, sep="\n")

print(bag1.equal(bag2), bag2.equal(bag1))

print(bag1.equal(bag3), bag3.equal(bag1))

print(bag2.equal(bag3), bag3.equal(bag2))

print(bag1.equal(bag_empty), bag_empty.equal(bag1))

print(bag_empty.equal(bag_empty))

print(bag1, bag2, bag3, bag_empty, sep="\n")

#Output:

#BAG: 6 elements. [1, 2, 3, 4, 5, 6]

#BAG: 6 elements. [6, 5, 4, 3, 2, 1]

#BAG: 5 elements. [1, 2, 3, 4, 5]

#BAG: 0 elements. []

#True True

#False False

#False False

#False False

#True

#BAG: 6 elements. [1, 2, 3, 4, 5, 6]

#BAG: 6 elements. [6, 5, 4, 3, 2, 1]

#BAG: 5 elements. [1, 2, 3, 4, 5]

#BAG: 0 elements. []

Solutions

Expert Solution

Each method implementation has been explained below.

  • add(value)

We can use the append method of the dynamic array to add elements(values) to our bag.

   def add(self, value: object) -> None:
       """
       uses append() method of dynamic array
       """
       self.da.append(value)
       return

  • remove(value)

This method removes the first occurence of the value from the bag. To implement this we iterate through the dynamic array and check if the element at each index is same as the value to be removed. Once we get the index, we can remove the element by calling remove_at_index(i) method of the dynamic array and return True immediately.

   def remove(self, value: object) -> bool:
       """
       gets the index of the element and removes it
       using remove_at_index(i)
       """
       for i in range(self.da.length()):
           if self.da.get_at_index(i) == value:
               self.da.remove_at_index(i)
               return True
       return False

  • count(value)

Here, again we iterate through the dynamic array. We initialize a variable n which keeps track of the count. Each time, we find our value in the dynamic array we increment n. Finally we return n, once the entire dynamic array has been checked.

   def count(self, value: object) -> int:
       """
       returns the count of element in the bag
       """
       n = 0
       for i in range(self.da.length()):
           if self.da.get_at_index(i) == value:
               n += 1
       return n

  • clear()

We simply remove all the elements from the dynamic array by calling remove_at_index(i). Note, that we iterate the dynamic array from the end to start, so that indices of other elements do not change when we remove an element from the dynamic array.

   def clear(self) -> None:
       """
       clears all elements from the bag
       """
       for i in range(self.da.length()-1, -1, -1):
           self.da.remove_at_index(i)

  • size()

This is simply the length of the dynamic array.

   def size(self) -> int:
       """
       returns the size of the bag
       """
       return self.da.length()

  • equal(second_bag)

Here, we first compare if the sizes of the two bag's are equal. If the sizes are equal, we check if the count of each element in our bag and second_bag are equal.

   def equal(self, second_bag: object) -> bool:
       """
       compares two bags and returns True if
           they have the same size and
           they have the same elements
       """
       if self.da.length() != second_bag.da.length():
           return False

       for i in range(self.da.length()):
           element = self.da.get_at_index(i)
           if (self.count(element) != second_bag.count(element)):
               return False
       return True

Screenshot of the code (included for readability)

Output

  


Related Solutions

1. Implement the graph ADT using the adjacency list structure. 2. Implement the graph ADT using...
1. Implement the graph ADT using the adjacency list structure. 2. Implement the graph ADT using the adjacency matrix structure. LANGUAGE IS IN JAVA Comment for any questions Data structures and algorithms
Write a code in c++ using dynamic array of structure and dynamic array list. Make a...
Write a code in c++ using dynamic array of structure and dynamic array list. Make a dummy list for a company which stores following information about its customers. Customer ID Customer Name Gender Total items purchased Item category 20% discount in percentage of total purchase amount. Use dynamic array to save at least 20 items by dividing them into 3 different categories. Make a dummy list of items that company sells by dividing them into two categorizes. Items has following...
3.1 Implement the stack ADT using array (4 marks) 3.1.1 Implement the pop() operation in the...
3.1 Implement the stack ADT using array 3.1.1 Implement the pop() operation in the stack (1 mark) Implement a stack class named Stack2540Array using array. The starter code is as follows. The instance variables and most operations are provided. You need to implement the pop operation. Make sure that your program checks whether the stack is empty in the pop operation. import java . io .*; import java . util .*; public class Stack2540Array { int CAPACITY = 128; int...
In C++, Design and implement an ADT that represents a triangle. The data for the ADT...
In C++, Design and implement an ADT that represents a triangle. The data for the ADT should include the three sides of the triangle but could also include the triangle’s three angles. This data should be in the private section of the class that implements the ADT. Include at least two initialization operations: one that provides default values for the ADT’s data, and another that sets this data to client-supplied values. These operations are the class’s constructors. The ADT also...
Implement a class Polynomial that uses a dynamic array of doubles to store the coefficients for...
Implement a class Polynomial that uses a dynamic array of doubles to store the coefficients for a polynomial. Much of this work can be modelled on the C++ dynamic array of ints List that we discussed in class. This class does not need the method the overloaded += operator. Your class should have the following methods: Write one constructor that takes an integer n for the degree of a term and a double coefficient c for the coefficient of the...
Data Structures and Algorithms Activity Requirement: Implement a queue using an array as its underline data...
Data Structures and Algorithms Activity Requirement: Implement a queue using an array as its underline data structure. Your queue should fully implemnted the following methods: first, push_back (enqueue), pop_front (dequeue), size, and isEmpty. Make sure to include a driver to test your newly implemented queue
Implement a Binary tree using an array using class.
Implement a Binary tree using an array using class.
Implement in C++ Design a BookstoreManager class which creates a dynamic array of type Book (don’t...
Implement in C++ Design a BookstoreManager class which creates a dynamic array of type Book (don’t use vectors), and provide an implementation for the following operations on books in the array 1)isEmpty() returns true if the array is empty, otherwise false 2)isFull() returns true if the array is full, otherwise false 3)listSize() prints the number of books in the array 4)print() prints the content of the array 5)insert(Book) asks the user to enter new book info, and it adds the...
Implement in C++ Design a BookstoreManager class which creates a dynamic array of type Book (don’t...
Implement in C++ Design a BookstoreManager class which creates a dynamic array of type Book (don’t use vectors), and provide an implementation for the following operations on books in the array 1)isEmpty() returns true if the array is empty, otherwise false 2)isFull() returns true if the array is full, otherwise false 3)listSize() prints the number of books in the array 4)print() prints the content of the array 5)insert(Book) asks the user to enter new book info, and it adds the...
[Point: 10] The instance of a list ADT using array is L = (10, 20, 30,...
[Point: 10] The instance of a list ADT using array is L = (10, 20, 30, 40, 50, 60). Find the output of following code segment or what is returned by each statement. remove(30);          find(50):                insert(7, 3):           findKth(4)             [Point: 5] The complexity of remove operation from a LIST ADT using array implementation is O(N). Explain why? [Point: 10] Show that the running time for the following segment of code is O(N3) without using the rule for loop. Make sure to...
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT