Домашни > Another brick in the wall > Решения > Решението на Даниел Манчевски

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

9 точки общо

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

  1class Material:
  2    def __init__(self, mass):
  3        self.mass = mass
  4
  5    @property
  6    def volume(self):
  7        return self.mass / self.density
  8
  9
 10class Concrete(Material):
 11    density = 2500
 12
 13
 14class Brick(Material):
 15    density = 2000
 16
 17
 18class Stone(Material):
 19    density = 1600
 20
 21
 22class Wood(Material):
 23    density = 600
 24
 25
 26class Steel(Material):
 27    density = 7700
 28
 29
 30class Factory:
 31    _base_materials = {
 32        "Concrete": Concrete,
 33        "Brick": Brick,
 34        "Stone": Stone,
 35        "Wood": Wood,
 36        "Steel": Steel,
 37    }
 38    _all_materials = {}
 39    _invalid = []
 40    _state_owned = []  # Hello comrade
 41
 42    def __init__(self):
 43        self.owned = []
 44
 45    def __call__(self, *args, **kwargs):
 46        if not args and not kwargs:
 47            raise ValueError("Materiali zabravi")
 48        if args and kwargs:
 49            raise ValueError("Gosho")
 50
 51        if kwargs:
 52            result = []
 53            for name, mass in kwargs.items():
 54                if name in Factory._base_materials:
 55                    material_class = Factory._base_materials[name]
 56                elif name in Factory._all_materials:
 57                    material_class = Factory._all_materials[name]
 58                else:
 59                    raise ValueError("Bratko kakvi sa tezi gluposti")
 60
 61                material_instance = material_class(mass)
 62
 63                self.owned.append(material_instance)
 64                self._state_owned.append(material_instance)
 65
 66                Factory._all_materials[name] = material_class
 67
 68                result.append(material_instance)
 69            return tuple(result)
 70        else:
 71            return self._handle_positional_arguments(args)
 72
 73    def _handle_positional_arguments(self, args):
 74        for arg in args:
 75            if arg in Factory._invalid:
 76                raise AssertionError("tova si go polzval bot")
 77
 78        for arg in args:
 79            Factory._invalid.append(arg)
 80
 81        all_class_names = []
 82        for arg in args:
 83            class_name_parts = arg.__class__.__name__.split("_")
 84            all_class_names.extend(class_name_parts)
 85        sorted_class_names = sorted(set(all_class_names))
 86        class_name = "_".join(sorted_class_names)
 87
 88        materials = {arg.__class__ for arg in args}
 89
 90        if class_name in Factory._all_materials:
 91            material_class = Factory._all_materials[class_name]
 92            mass = sum(arg.mass for arg in args)
 93            material_instance = material_class(mass)
 94            self.owned.append(material_instance)
 95            self._state_owned.append(material_instance)
 96
 97        else:
 98            mass = sum(arg.mass for arg in args)
 99
100            sumz = 0
101            for cls in sorted_class_names:
102                sumz += Factory._base_materials[cls].density
103            avg_density = sumz / len(materials)
104
105            DynamicClass = type(class_name, (Material,), {"density": avg_density})
106
107            obj = DynamicClass(mass)
108
109            Factory._all_materials[class_name] = DynamicClass
110            self.owned.append(obj)
111            self._state_owned.append(obj)
112
113            material_instance = obj
114
115        for arg in args:
116            if arg in self.owned:
117                self.owned.remove(arg)
118                self._state_owned.remove(arg)
119
120        return material_instance
121
122    def can_build(self, volume_needed):
123        total_volume = sum(material.volume for material in self.owned)
124        return total_volume >= volume_needed
125
126    @staticmethod
127    def can_build_together(volume_needed):
128        total_volume = sum(material.volume for material in Factory._state_owned)
129        return total_volume >= volume_needed

......F...
======================================================================
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: 4.0625 != 6.77 within 2 places (2.7074999999999996 difference)

----------------------------------------------------------------------
Ran 10 tests in 0.040s

FAILED (failures=1)

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