Домашни > Another brick in the wall > Решения > Решението на Камелия Тодорова

Резултати
5 точки от тестове
0 точки от учител

5 точки общо

5 успешни теста
5 неуспешни теста
Код
Скрий всички коментари

  1MATERIALS_DENSITIES = {"Concrete" : 2500, "Brick" : 2000, "Stone" : 1600, "Wood" : 600, "Steel" : 7700}
  2
  3class Material:
  4   
  5    def __init__(self, weight):
  6        self.name = type(self).__name__
  7        self.weight = weight
  8        self.used = False
  9        if self.name in MATERIALS_DENSITIES:
 10            self.density = MATERIALS_DENSITIES[self.name]
 11    
 12    
 13    @property
 14    def volume(self):
 15        if self.used:
 16            return 0
 17        return float(self.weight / self.density)
 18    
 19    def mark_as_used(self):
 20        self.used = True
 21    
 22
 23class Concrete(Material):
 24    pass
 25
 26
 27class Brick(Material):
 28    pass
 29
 30
 31class Stone(Material):
 32   pass
 33
 34
 35class Wood(Material):
 36    pass
 37
 38
 39class Steel(Material):
 40    pass
 41
 42
 43class Factory():
 44    MATERIALS = {"Concrete" : Concrete, "Brick" : Brick, "Stone" : Stone, "Wood" : Wood, "Steel" : Steel}
 45    dynamicly_created_materials = {}
 46    all_instances = []
 47    
 48    def __init__(self):
 49        self.current_factory_instances = []
 50
 51    def __call__(self, *args, **kwargs): 
 52        if (args and kwargs) or (not args and not kwargs):
 53            raise ValueError("Invalid arguments.")
 54        
 55        elif args:
 56            return self._create_dynamic_material(*args)
 57        
 58        elif kwargs:
 59            result_tuple = ()
 60            for name, weight in kwargs.items():
 61                if name in self.MATERIALS:
 62                    material_class = self.MATERIALS[name]
 63                elif name in self.dynamicly_created_materials:
 64                    material_class = self.dynamicly_created_materials[name]
 65                else:
 66                    raise ValueError("Invalid material.")
 67                result_tuple += (material_class(weight), )
 68            self.current_factory_instances += list(result_tuple)
 69            return result_tuple
 70            
 71    
 72    def _create_dynamic_material(self, *args):
 73        for curr_material in args:
 74            if not isinstance(curr_material, Material):
 75                raise ValueError("Invalid material.")
 76            if curr_material.used:
 77                raise AssertionError("This material has been used already.")
 78        for curr_material in args:
 79            curr_material.mark_as_used()
 80            
 81        all_names = [material.name for material in args]
 82        split_elements = [name for element in all_names for name in element.split("_")]
 83        elements = sorted(split_elements)
 84        new_class_name =  "_".join(elements)
 85        new_weight = sum(material.weight for material in args )
 86
 87        if new_class_name not in self.dynamicly_created_materials:
 88            
 89            class DynamicMaterial(Material):
 90                
 91                def __init__(self, weight):
 92                    super().__init__(weight)
 93                    self.density = sum(MATERIALS_DENSITIES[curr_class_name] for curr_class_name in elements) / len(elements)
 94                    self.name = new_class_name
 95                
 96            self.dynamicly_created_materials[new_class_name] = DynamicMaterial
 97            
 98        curr_instance = self.dynamicly_created_materials[new_class_name](new_weight)
 99        if not curr_instance in Factory.all_instances:
100           Factory.all_instances.append(curr_instance)
101        if not curr_instance in self.current_factory_instances:
102           self.current_factory_instances.append(curr_instance)
103        return curr_instance
104    
105    def can_build(self, value):
106        return sum(material.volume for material in self.current_factory_instances) >= value
107    
108    @classmethod
109    def can_build_together(cls, value):
110        return sum(material.volume for material in cls.all_instances) >= value
111
112        

.F..FFFF..
======================================================================
FAIL: test_can_build (test.TestFactory.test_can_build)
Test can_build methods.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 178, in test_can_build
self.assertTrue(self.factory2.can_build_together(6.0))
AssertionError: False is not true

======================================================================
FAIL: test_named_arguments_with_dynamically_created_classes (test.TestFactory.test_named_arguments_with_dynamically_created_classes)
Test dynamically created classes uniqueness.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 146, in test_named_arguments_with_dynamically_created_classes
self.assertEqual(result1.__class__.__name__,
AssertionError: 'DynamicMaterial' != 'Brick_Concrete_Steel_Stone_Wood'
- DynamicMaterial
+ Brick_Concrete_Steel_Stone_Wood

======================================================================
FAIL: test_positional_arguments_multiple_argument_from_initial_set (test.TestFactory.test_positional_arguments_multiple_argument_from_initial_set)
Test calling a factory using multiple positional arguments.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 94, in test_positional_arguments_multiple_argument_from_initial_set
self.assertEqual(result.__class__.__name__, 'Brick_Concrete_Wood')
AssertionError: 'DynamicMaterial' != 'Brick_Concrete_Wood'
- DynamicMaterial
+ Brick_Concrete_Wood

======================================================================
FAIL: test_positional_arguments_multiple_argument_with_dynamics (test.TestFactory.test_positional_arguments_multiple_argument_with_dynamics)
Test calling a factory using multiple positional arguments.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 128, in test_positional_arguments_multiple_argument_with_dynamics
self.assertEqual(mega_material.__class__.__name__,
AssertionError: 'DynamicMaterial' != 'Brick_Concrete_Steel_Stone_Wood'
- DynamicMaterial
+ Brick_Concrete_Steel_Stone_Wood

======================================================================
FAIL: test_positional_arguments_single_argument (test.TestFactory.test_positional_arguments_single_argument)
Test calling a factory using a sigle positional argument.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 80, in test_positional_arguments_single_argument
self.assertIs(type(concrete2), solution.Concrete)
AssertionError: <class 'solution.Factory._create_dynamic_material.<locals>.DynamicMaterial'> is not <class 'solution.Concrete'>

----------------------------------------------------------------------
Ran 10 tests in 0.015s

FAILED (failures=5)

Дискусия
История
Това решение има само една версия.