diff --git a/resources/knapsack.py b/resources/knapsack.py index ea50f72da27e9127e0ab177dd7d844c094e025c7..332021aeca71fc8963d08309d6b0b89c212b4092 100644 --- a/resources/knapsack.py +++ b/resources/knapsack.py @@ -34,12 +34,17 @@ class FractionalKnapsackAlgorithm(): """ Sets group of items to choose from. :param item_set: Set of items, essentially in JSON format. + :return: Bool indicating if item set allocation succeeded. """ # First validate item set. if self.validate_item_set(item_set): # Validation passed. Set values. self._item_set_ = item_set self._items_populated_ = True + return True + else: + # Validation failed. + return False def validate_item_set(self, item_set): """ @@ -84,6 +89,21 @@ class FractionalKnapsackAlgorithm(): # Check that 'cost' key is parsable as int. int(str(item['cost']).strip()) + def add_item_to_item_set(self, item): + """ + Adds dictionary item to item set. + :param item: Potential new item to add to "item set". + :return: Bool indicating if item was successfully added or not. + """ + # First validate that item matches requirements. + if self.validate_item_set([item]): + # Validation success. + self._item_set_.append(item) + self._items_populated_ = True + return True + else: + # Validation failed. Item not added. + return False def set_max_weight(self, max_weight): """ diff --git a/tests/resources/knapsack.py b/tests/resources/knapsack.py index 656acc8bb4ae880094180f4003083b4c6a883641..3f8f6edc47a2fa9a797ed9749f6e44fee3aeeff6 100644 --- a/tests/resources/knapsack.py +++ b/tests/resources/knapsack.py @@ -65,47 +65,47 @@ class TestKnapsack(unittest.TestCase): self.assertFalse(self.knapsack._weight_populated_) def test_set_item_set_success(self): - # Test success with set 1. - self.knapsack.set_item_set(self.item_set_1) + # Test success with set 1. + self.assertTrue(self.knapsack.set_item_set(self.item_set_1)) self.assertEqual(self.knapsack._item_set_, self.item_set_1) self.assertTrue(self.knapsack._items_populated_) # Test success with set 2. - self.knapsack.set_item_set(self.item_set_2) + self.assertTrue(self.knapsack.set_item_set(self.item_set_2)) self.assertEqual(self.knapsack._item_set_, self.item_set_2) self.assertTrue(self.knapsack._items_populated_) def test_set_item_set_failure(self): with self.subTest('Arg is not array of dicts'): # Passed None. - self.knapsack.set_item_set(None) + self.assertFalse(self.knapsack.set_item_set(None)) self.assertEqual(self.knapsack._item_set_, []) self.assertFalse(self.knapsack._items_populated_) # Passed array with no dict items. - self.knapsack.set_item_set([1, 2, 3]) + self.assertFalse(self.knapsack.set_item_set([1, 2, 3])) self.assertEqual(self.knapsack._item_set_, []) self.assertFalse(self.knapsack._items_populated_) with self.subTest('Dict item must have "benefit" and "cost" keys.'): # Passed dict item missing "cost" key. - self.knapsack.set_item_set([{'benefit': 1}]) + self.assertFalse(self.knapsack.set_item_set([{'benefit': 1}])) self.assertEqual(self.knapsack._item_set_, []) self.assertFalse(self.knapsack._items_populated_) # Passed dict item missing "benefit" key. - self.knapsack.set_item_set([{'cost': 1}]) + self.assertFalse(self.knapsack.set_item_set([{'cost': 1}])) self.assertEqual(self.knapsack._item_set_, []) self.assertFalse(self.knapsack._items_populated_) with self.subTest('Item values must be parsable as integers.'): # Passed bad value for "benefit" key. - self.knapsack.set_item_set([{'benefit': 'a', 'cost': 1}]) + self.assertFalse(self.knapsack.set_item_set([{'benefit': 'a', 'cost': 1}])) self.assertEqual(self.knapsack._item_set_, []) self.assertFalse(self.knapsack._items_populated_) # Passed bad value for "cost" key. - self.knapsack.set_item_set([{'benefit': 1, 'cost': 'a'}]) + self.assertFalse(self.knapsack.set_item_set([{'benefit': 1, 'cost': 'a'}])) self.assertEqual(self.knapsack._item_set_, []) self.assertFalse(self.knapsack._items_populated_) @@ -141,6 +141,41 @@ class TestKnapsack(unittest.TestCase): with self.assertRaises(ValueError): self.knapsack._validate_item_set([{'benefit': 1, 'cost': 'a'}]) + def test_add_item_to_item_set_success(self): + # Test with 1 item. + item_1 = { + 'benefit': 5, + 'cost': 2, + } + self.assertTrue(self.knapsack.add_item_to_item_set(item_1)) + self.assertEqual(self.knapsack._item_set_, [item_1]) + self.assertTrue(self.knapsack._items_populated_) + + # Test with 1 item. + item_2 = { + 'benefit': 3, + 'cost': 1, + } + self.assertTrue(self.knapsack.add_item_to_item_set(item_2)) + self.assertEqual(self.knapsack._item_set_, [item_1, item_2]) + self.assertTrue(self.knapsack._items_populated_) + + # Test with 1 item. + item_3 = { + 'benefit': 6, + 'cost': 3, + } + self.assertTrue(self.knapsack.add_item_to_item_set(item_3)) + self.assertEqual(self.knapsack._item_set_, [item_1, item_2, item_3]) + self.assertTrue(self.knapsack._items_populated_) + + # Assume works with all further n+1 items. + + def test_add_item_to_item_set_failure(self): + self.assertFalse(self.knapsack.add_item_to_item_set([])) + self.assertEqual(self.knapsack._item_set_, []) + self.assertFalse(self.knapsack._items_populated_) + def test_set_max_weight_success(self): self.knapsack.set_max_weight(1) self.assertEqual(self.knapsack._max_weight_, 1)