Домашни > Another brick in the wall > Решения > Решението на Радосвета Шопова

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

7 точки общо

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

  1class Materials:
  2    """Base class for all materials."""
  3    def __init__(self, weight):
  4        self.weight = weight
  5        self.used_before = False
  6
  7    @property
  8    def volume(self):
  9        return self.weight / self.density
 10
 11    def mark_used_before(self):
 12        self.used_before = True
 13
 14    def is_used_before(self):
 15        return self.used_before
 16
 17
 18class Concrete(Materials):
 19    density = 2500
 20
 21
 22class Brick(Materials):
 23    density = 2000
 24
 25
 26class Stone(Materials):
 27    density = 1600
 28
 29
 30class Wood(Materials):
 31    density = 600
 32
 33
 34class Steel(Materials):
 35    density = 7700
 36
 37
 38MATERIALS_TYPES = {"Concrete": Concrete, "Brick": Brick, "Stone": Stone,
 39                   "Wood": Wood, "Steel": Steel}
 40
 41ALLOY_CLASSES = {}
 42ALL_MATERIALS = []
 43
 44
 45class Factory:
 46    """Class that simulat a factory for creat materials and alloys from them."""
 47    def __init__(self):
 48        self.all_materials_for_instance = []
 49
 50    def _sort_material_names(self, materials_name):
 51        """Sort the names of the materials alphabetically."""
 52        all_parts = []
 53        for name in materials_name:
 54            parts = name.split("_")
 55            all_parts.extend(parts)
 56
 57        all_parts.sort()
 58        return "_".join(all_parts)
 59
 60    def __call__(self, *args, **kwargs):
 61        """Creat new materials or alloys and add them to the factory's materials list."""
 62        if not args and not kwargs:
 63            raise ValueError("Cannot call this function without arguments.")
 64
 65        if args and kwargs:
 66            raise ValueError(
 67                "Cannot call this function with mix positional and keyword arguments.")
 68
 69        if kwargs:
 70            instances = []
 71            for key, weight in kwargs.items():
 72                if key in MATERIALS_TYPES:
 73                    materials = MATERIALS_TYPES[key](weight)
 74                    instances.append(materials)
 75                    self.all_materials_for_instance.append(materials)
 76                    ALL_MATERIALS.append(materials)
 77                elif key in ALLOY_CLASSES:
 78                    materials = ALLOY_CLASSES[key](weight)
 79                    instances.append(materials)
 80                    self.all_materials_for_instance.append(materials)
 81                    ALL_MATERIALS.append(materials)
 82                else:
 83                    raise ValueError(f"This type - {key} - not found.")
 84            return tuple(instances)
 85
 86        if args:
 87            for material in args:
 88                if not isinstance(material, Materials):
 89                    raise ValueError("Arguments must be instances of materials.")
 90
 91                if material.is_used_before():
 92                    raise AssertionError("This material has already been used.")
 93                material.mark_used_before()
 94                self.all_materials_for_instance.append(material)
 95                ALL_MATERIALS.append(material)
 96
 97            materials_name = sorted(type(material).__name__ for material in args)
 98            alloy_name = self._sort_material_names(materials_name)
 99
100            if alloy_name in ALLOY_CLASSES:
101                alloy_class = ALLOY_CLASSES[alloy_name]
102            else:
103                alloy_density = sum(type(material).density for material in args) / len(args)
104                alloy_class = type(alloy_name, (Materials,), {"density": alloy_density})
105                ALLOY_CLASSES[alloy_name] = alloy_class
106
107            alloy_weight = sum(material.weight for material in args)
108            self.all_materials_for_instance.append(alloy_class(alloy_weight))
109            ALL_MATERIALS.append(alloy_class(alloy_weight))
110            return alloy_class(alloy_weight)
111
112    def can_build(self, current_volume):
113        """Check all materials created by the current instance."""
114        return sum(material.volume for material in self.all_materials_for_instance
115                   if not material.is_used_before()) >= current_volume
116
117    @classmethod
118    def can_build_together(cls, current_volume):
119        """Check all materials created by all instances"""
120        return sum(material.volume for material in ALL_MATERIALS
121                   if not material.is_used_before()) >= current_volume

.....FFF..
======================================================================
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 116, in test_positional_arguments_multiple_argument_from_initial_set
concrete_wood = self.factory1(concrete, wood)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 92, in __call__
raise AssertionError("This material has already been used.")
AssertionError: This material has already been used.

======================================================================
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 130, in test_positional_arguments_multiple_argument_with_dynamics
self.assertAlmostEqual(mega_material.volume, 6.77, places=2) # mass=19500, density=2880
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 5.661290322580645 != 6.77 within 2 places (1.1087096774193546 difference)

======================================================================
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.Concrete'> is not <class 'solution.Concrete'>

----------------------------------------------------------------------
Ran 10 tests in 0.010s

FAILED (failures=3)

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