Question: 5.10) Can you please help me with this python assignment. Pythons for loop allows the programmer to add or remove items in the collection over

5.10)

Can you please help me with this python assignment.

Pythons 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 collections __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.
  3. 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.
  4. In the mutator method clear() set modCount to 0
  5. 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. ( I will post this file too )

Your program's output should look like the following:

Testing

The list of items added is: [9, 8, 2, 3, 4, 7, 1, 5, 10, 6]

Expect the bag's string, in ascending order: {9, 8, 2, 3, 4, 7, 1, 5, 10, 6}

Add 5 more items to test increasing the array size:

Expect the bag's string: {9, 8, 2, 3, 4, 7, 1, 5, 10, 6, 11, 12, 13, 14, 15}

Traceback (most recent call last):

File "testbag.py", line 26, in

test(ArrayBag)

File "testbag.py", line 24, in test

for i in b:

File "/root/sandbox/arraybag.py", line 48, in __iter__

raise AttributeError("Mutation not allowed in loop")

AttributeError: Mutation not allowed in loop

The output list may vary given that it's a random set of numbers range(1, 11)

File: arraybag.py

"""

Project 5.10

File: arraybag.py

"""

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

File: testbag.py ( To test the code)

"""

File: testbag.py

A tester program for bag implementations.

"""

from arraybag import ArrayBag

from random import shuffle

def test(bagType):

"""Expects a bag type as an argument and runs some tests

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)

print("Expect the bag's string, in ascending order:", b)

print("Add 5 more items to test increasing the array size:")

for i in range(11, 16):

b.add(i)

print("Expect the bag's string:", b)

"""Should raise Attribute Error"""

for i in b:

b.add(i)

test(ArrayBag)

Step by Step Solution

There are 3 Steps involved in it

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Databases Questions!