Answered step by step
Verified Expert Solution
Question
1 Approved Answer
Part 1 ====== distributeBag() function ------------------------ Read the function header to understand what this function does. Pay particular attention to its preconditions and postconditions. You
Part 1 ====== distributeBag() function ------------------------ Read the function header to understand what this function does. Pay particular attention to its preconditions and postconditions. You need to add your code to this function where indicated. Do not change any of its existing code. Note that this function's return statement returns 2 objects: The red bag and the blue bag objects. Returning multiple objects in a single return statement is a unique Python feature. The balls --------- The balls in the bags are objects of class Ball. This class is provided under the assignment in the course web page. Also provided there is a ball tester, which makes it easy to see how to use a ball. A red ball's color is the string "red". A blue ball's color is the string "blue". Moving the balls ---------------- Moving the balls means they need to end up in the right bag. It also means they should not be in the starting bag after your code completes. For each test case, a reference to the starting bag is passed in as a function parameter. Changes you make to this bag parameter result in changes to the bag used at the point of call. This is because parameters in Python are passed by reference, rather than by copied value. Your code should be general enough to handle all 3 sets of test data. Do NOT write 3 separate blocks of code, one for each specific test set. Instead, your single solution should work for any of these test cases. You should use a for loop on the original mixed bag. You do NOT need to remove the balls from the mixed bag as you see them. You can wait until after all the ball references have been added to the unicolor bags. Using references is a shallow copy of the balls. This is OK here because you will be removing the ball references from the mixed bag. This means there will not be any duplicate references in differebt bags to worry about. Keep it simple -------------- Do not overthink/overcomplicate this. Solutions are simple and easy to understand. There is more than one possible coding solution. Part 2 ====== printBag() function ------------------- This function takes a bag as a paramater. Look at the expected output document to see what it is supposed to print. It must iterate through the given bag. Each item must be printed on a separate line. To get a string version of a ball item, just use str(item). Notice that it must print "empty" if the bag is empty. Notice that it must print a blank line after the bag output.
~~~~~~~~~~~~~~~~~~~
# This program exercises bags:# Replace any "" comments with your own code statement(s) # to accomplish the specified task.# Do not change any other code.# The following files must be in the same folder:# abstractcollection.py# abstractbag.py# arraybag.py# arrays.py# ball.pyfrom arraybag import ArrayBagfrom ball import Ball# Part 1:# This function takes a bag that has red and blue balls in it# and moves the balls to two other bags: one to hold the red# balls and one to hold the blue balls.## Preconditions:# bag - an ArrayBag containing zero or more red and blue Ball objects.## Postconditions:# returns - a bag containing the red balls and# a bag containing the blue balls.# The original bag should be emptied.def distributeBag(bag):redBag = ArrayBag()blueBag = ArrayBag()# Move the balls to the appropriate bags:## Return the 2 bags:return (redBag, blueBag)# Part 2:# This function prints the items in a bag, each on a separate line.def printBag(bag):## Test 1:print("Test 1:")bag1 = ArrayBag([Ball("red", 1),Ball("red", 2),Ball("red", 3),Ball("blue", 1),Ball("blue", 2),Ball("blue", 3)])print("Original mixed bag:")printBag(bag1)redBag, blueBag = distributeBag(bag1)print("Red bag:")printBag(redBag)print("Blue bag:")printBag(blueBag)print("Final mixed bag:")printBag(bag1)# Test 2:print("Test 2:")bag1 = ArrayBag([Ball("red", 1),Ball("red", 2),])print("Original mixed bag:")printBag(bag1)redBag, blueBag = distributeBag(bag1)print("Red bag:")printBag(redBag)print("Blue bag:")printBag(blueBag)print("Final mixed bag:")printBag(bag1)# Test 3:print("Test 3:")bag1 = ArrayBag()print("Original mixed bag:")printBag(bag1)redBag, blueBag = distributeBag(bag1)print("Red bag:")printBag(redBag)print("Blue bag:")printBag(blueBag)print("Final mixed bag:")printBag(bag1)~~~~~~~~~~~~~~~~~~~# Ball class class Ball: # Class variable DEFAULT_RADIUS = 1 # Constructor: def __init__(self, color, radius = DEFAULT_RADIUS): self.color = color; self.radius = radius; # Special methods: def __eq__(self, other): if self is other: return True if (type(self) != type(other)) or \ (self.color != other.color) or \ (self.radius != other.radius): return False return True def __str__(self): return (self.color + " ball, radius " + str(self.radius)) # Accessor methods: def getColor(self): return self.color def getRadius(self): return self.radius # Mutator methods: def setColor(self, color): self.color = color def setRadius(self, radius): self.radius = radius~~~~~~~~~~~~~~~~~~~""" File: abstractcollection.py Copyright 2015 by Ken Lambert """ class AbstractCollection(object): """An abstract collection implementation.""" # Constructor def __init__(self, sourceCollection = None): """Sets the initial state of self, which includes the contents of sourceCollection, if it's present.""" self._size = 0 self._modCount = 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, using [] as delimiters.""" return "[" + ", ".join(map(str, self)) + "]" def __eq__(self, other): """Returns True if self equals other, or False otherwise. Compares pairs of items in the two sequences generated by the iterators on self and other.""" if self is other: return True if type(self) != type(other) or \ len(self) != len(other): return False otherIter = iter(other) for item in self: if item != next(otherIter): return False return True def __add__(self, other): """Returns a new collection containing the contents of self and other.""" result = type(self)(self) for item in other: result.add(item) return result def count(self, item): """Returns the number of instance of item in self.""" counter = 0 for nextItem in self: if item == nextItem: counter += 1 return counter # These methods track and update the modCount, which is used to # prevent mutations within the context of an iterator (for loop) def getModCount(self): """Returns the number of modifications to the collection.""" return self._modCount def incModCount(self): """Increments the number of modifications to the collection.""" self._modCount += 1 ~~~~~~~~~~~~~~~~""" File: abstractbag.py Copyright 2015 by Ken Lambert """ from abstractcollection import AbstractCollection class AbstractBag(AbstractCollection): """Repository for common bag data and methods.""" # Constructor def __init__(self, sourceCollection = None): """Sets the initial state of self, which includes the contents of sourceCollection, if it's present.""" AbstractCollection.__init__(self, sourceCollection) # Accessor methods def __str__(self): """Returns the string rep of the bag.""" result = AbstractCollection.__str__(self) return "{" + result[1:-1] + "}" 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~~~~~~~~~~~~~~~~~~~~~""" File: arraybag.py Copyright 2015 by Ken Lambert """ from arrays import Array from abstractbag import AbstractBag class ArrayBag(AbstractBag): """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) AbstractBag.__init__(self, sourceCollection) def __iter__(self): """Supports iteration over a view of self.""" modCount = self.getModCount() cursor = 0 while cursor < len(self): yield self._items[cursor] if modCount != self.getModCount(): raise AttributeError("Illegal modification of backing store") cursor += 1 # Mutator methods def clear(self): """Makes self become empty.""" self._size = 0 self._modCount = 0 self._items = Array(ArrayBag.DEFAULT_CAPACITY) def add(self, item): """Adds item to self.""" # Resize array if necessary if len(self) == len(self._items): tempArray = Array(len(self) * 2) for i in range(len(self)): tempArray[i] = self._items[i] self._items = tempArray self._items[len(self)] = item self._size += 1 self.incModCount() 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 self.incModCount() # Resize array if necessary if len(self) <= .25 * len(self._items) and \ ArrayBag.DEFAULT_CAPACITY <= len(self._items) // 2: tempArray = Array(len(self._items) // 2) for i in range(len(self)): tempArray[i] = self._items[i] self._items = tempArray~~~~~~~~~~~~~~~~~~~""" File: arrays.py Copyright 2015 by Ken Lambert An Array is a restricted list whose clients can use only [], len, iter, and str. To instantiate, use= array( , ) The fill value is None by default. """ class Array(object): """Represents an array.""" def __init__(self, capacity, fillValue = None): """Capacity is the static size of the array. fillValue is placed at each position.""" self._items = list() for count in range(capacity): self._items.append(fillValue) def __len__(self): """-> The capacity of the array.""" return len(self._items) def __str__(self): """-> The string representation of the array.""" return str(self._items) def __iter__(self): """Supports iteration over a view of an array.""" return iter(self._items) def __getitem__(self, index): """Subscript operator for access at index.""" return self._items[index] def __setitem__(self, index, newItem): """Subscript operator for replacement at index.""" self._items[index] = newItem ~~~~~~~~~~~~~~~~~~~~OutputTest 1: Original mixed bag: red ball, radius 1 red ball, radius 2 red ball, radius 3 blue ball, radius 1 blue ball, radius 2 blue ball, radius 3 Red bag: red ball, radius 1 red ball, radius 2 red ball, radius 3 Blue bag: blue ball, radius 1 blue ball, radius 2 blue ball, radius 3 Final mixed bag: empty Test 2: Original mixed bag: red ball, radius 1 red ball, radius 2 Red bag: red ball, radius 1 red ball, radius 2 Blue bag: empty Final mixed bag: empty Test 3: Original mixed bag: empty Red bag: empty Blue bag: empty Final mixed bag: empty
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
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