Python’s for loop allows the programmer to add or remove items in the collection over which the loop is iterating. Some designers worry that changing the structure of a collection during iteration might cause program crashes. The remedy is to make the for loop read-only, by disallowing mutations to the collection during iteration. You can detect such mutations by keeping a count of them and determining if this count goes up at any point within the collection’s __iter__ method. When this happens, you can raise an exception to prevent the computation

C++ Programming: From Problem Analysis to Program Design
8th Edition
ISBN:9781337102087
Author:D. S. Malik
Publisher:D. S. Malik
Chapter18: Stacks And Queues
Section: Chapter Questions
Problem 16PE: The implementation of a queue in an array, as given in this chapter, uses the variable count to...
icon
Related questions
Question

Python’s for loop allows the programmer to add or remove items in the collection over which the loop is iterating. Some designers worry that changing the structure of a collection during iteration might cause program crashes. The remedy is to make the for loop read-only, by disallowing mutations to the collection during iteration. You can detect such mutations by keeping a count of them and determining if this count goes up at any point within the collection’s __iter__ method. When this happens, you can raise an exception to prevent the computation from going forward.

In the arraybag.py file complete the following in the ArrayBag class:

  1. In the __init__ method, include a new instance variable named modCount, which is set to 0.
  2. In the __iter__ method include a temporary variable named modCount, which is set initially to the value of the instance variable self.modCount.
    • Immediately after an item is yielded within the __iter__ method, you raise an exception if the values of the two mod counts are not equal.
  3. In the mutator method clear() set modCount to 0
  4. In the mutator methods add() and remove() increment the modCount variable.

To test your implementation of ArrayBag run the test method in the testbag.py file.

from arrays import Array

 

class ArrayBag(object):

    """An array-based bag implementation."""

 

    # Class variable

    DEFAULT_CAPACITY = 10

 

    # Constructor

    def __init__(self, sourceCollection = None):

        """Sets the initial state of self, which includes the

        contents of sourceCollection, if it's present."""

        self.items = Array(ArrayBag.DEFAULT_CAPACITY)

        self.size = 0

        if sourceCollection:

            for item in sourceCollection:

                self.add(item)

 

    # Accessor methods

    def isEmpty(self):

        """Returns True if len(self) == 0, or False otherwise."""

        return len(self) == 0

    

    def __len__(self):

        """Returns the number of items in self."""

        return self.size

 

    def __str__(self):

        """Returns the string representation of self."""

        return "{" + ", ".join(map(str, self)) + "}"

 

    def __iter__(self):

        """Supports iteration over a view of self.

        Raises Attribute error if mutation occurs

        within the loop."""

        cursor = 0

        while cursor < len(self):

            yield self.items[cursor]

            cursor += 1

 

    def __add__(self, other):

        """Returns a new bag containing the contents

        of self and other."""

        result = ArrayBag(self)

        for item in other:

            result.add(item)

        return result

 

    def clone(self):

        """Returns a copy of self."""

        return ArrayBag(self)

 

    def __eq__(self, other):

        """Returns True if self equals other,

        or False otherwise."""

        if self is other: return True

        if type(self) != type(other) or \

           len(self) != len(other):

            return False

        for item in self:

            if self.count(item) != other.count(item):

                return False

        return True

 

    def count(self, item):

        """Returns the number of instances of item in self."""

        total = 0

        for nextItem in self:

            if nextItem == item:

                total += 1

        return total

 

    # Mutator methods

    def clear(self):

        """Makes self become empty."""

        self.size = 0

        self.items = Array(ArrayBag.DEFAULT_CAPACITY)

 

    def add(self, item):

        """Adds item to self."""

        # Check array memory here and increase it if necessary

        if len(self) == len(self.items):

            temp = Array(2 * len(self))

            for i in range(len(self)):

                temp[i] = self.items[i]

            self.items = temp

        self.items[len(self)] = item

        self.size += 1

 

    def remove(self, item):

        """Precondition: item is in self.

        Raises: KeyError if item in not in self.

        Postcondition: item is removed from self."""

        # Check precondition and raise if necessary

        if not item in self:

            raise KeyError(str(item) + " not in bag")

        # Search for the index of the target item

        targetIndex = 0

        for targetItem in self:

            if targetItem == item:

                break

            targetIndex += 1

        # Shift items to the left of target up by one position

        for i in range(targetIndex, len(self) - 1):

            self.items[i] = self.items[i + 1]

        # Decrement logical size

        self.size -= 1

        # Check array memory here and decrease it if necessary

        if len(self) <= len(self.items) // 4 and \

           2 * len(self) >= ArrayBag.DEFAULT_CAPACITY:

            temp = Array(len(self.items) // 2)

            for i in range(len(self)):

                temp[i] = self.items[i]

            self.items = temp

       

Instructions
Python's for loop allows the
programmer to add or remove items in
the collection over which the loop is
iterating. Some designers worry that
changing the structure of a collection
during iteration might cause program
crashes. The remedy is to make the for
loop read-only, by disallowing mutations
to the collection during iteration. You can
detect such mutations by keeping a
count of them and determining if this
count goes up at any point within the
collection's __iter__ method. When
this happens, you can raise an exception
to prevent the computation from going
forward.
In the arraybag.py file complete the
arraybag.py
20
21
X testbag.py
1
"*"
2 File: testbag.py
3 Author: Ken Lambert
4 A tester program for bag implementations.
5 """
6
7 from arraybag import ArrayBag
8 from random import shuffle
9
10 def test (bagType):
11
12
13
14
15
16
17
18
19
X +
"""Expects a bag type as an argument and runs som
on objects of that type."""
print("Testing", bagType)
lyst = list (range(1, 11))
shuffle(lyst)
print("The list of items added is:", lyst)
b = bagType(lyst)
size:")
print("Expect the bag's string, in ascending order
print("Add 5 more items to test increasing the ar
for i in range (11, 16):
b.add(i)
>_ Terminal
X
python3 arraybag.py
+
Transcribed Image Text:Instructions Python's for loop allows the programmer to add or remove items in the collection over which the loop is iterating. Some designers worry that changing the structure of a collection during iteration might cause program crashes. The remedy is to make the for loop read-only, by disallowing mutations to the collection during iteration. You can detect such mutations by keeping a count of them and determining if this count goes up at any point within the collection's __iter__ method. When this happens, you can raise an exception to prevent the computation from going forward. In the arraybag.py file complete the arraybag.py 20 21 X testbag.py 1 "*" 2 File: testbag.py 3 Author: Ken Lambert 4 A tester program for bag implementations. 5 """ 6 7 from arraybag import ArrayBag 8 from random import shuffle 9 10 def test (bagType): 11 12 13 14 15 16 17 18 19 X + """Expects a bag type as an argument and runs som on objects of that type.""" print("Testing", bagType) lyst = list (range(1, 11)) shuffle(lyst) print("The list of items added is:", lyst) b = bagType(lyst) size:") print("Expect the bag's string, in ascending order print("Add 5 more items to test increasing the ar for i in range (11, 16): b.add(i) >_ Terminal X python3 arraybag.py +
Expert Solution
trending now

Trending now

This is a popular solution!

steps

Step by step

Solved in 2 steps

Blurred answer
Knowledge Booster
Mergesort
Learn more about
Need a deep-dive on the concept behind this application? Look no further. Learn more about this topic, computer-science and related others by exploring similar questions and additional content below.
Similar questions
  • SEE MORE QUESTIONS
Recommended textbooks for you
C++ Programming: From Problem Analysis to Program…
C++ Programming: From Problem Analysis to Program…
Computer Science
ISBN:
9781337102087
Author:
D. S. Malik
Publisher:
Cengage Learning