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

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

7 точки общо

7 успешни теста
3 неуспешни теста
Код (WHAT THE FUCK IS A KILOMETER)
Скрий всички коментари

  1#"We're going to build a wall"
  2class Material:
  3    def __init__(self, mass):
  4        if not isinstance(mass, int):
  5            raise ValueError("Ти олигофрен ли си, трябва да е цяло число")
  6        self.mass = mass
  7        self._used = False
  8
  9    @property
 10    def volume(self):
 11        return self.mass / self.density
 12
 13    def mark_as_used(self):
 14        if self._used:
 15            raise AssertionError("Даже не се и учудвам, че слагаш нещо което е вече сложено")
 16        self._used = True
 17
 18
 19class Concrete(Material):
 20    density = 2500
 21
 22
 23class Brick(Material):
 24    density = 2000
 25
 26
 27class Stone(Material):
 28    density = 1600
 29
 30
 31class Wood(Material):
 32    density = 600
 33
 34
 35class Steel(Material):
 36    density = 7700 #Стоманата не е по-плътна от един венест сникерс
 37
 38material_classes = {
 39    "Concrete": Concrete,
 40    "Brick": Brick,
 41    "Stone": Stone,
 42    "Wood": Wood,
 43    "Steel": Steel
 44}
 45
 46class Factory:
 47    all_factories = []
 48    dynamic_classes = {}
 49
 50    def __init__(self):
 51        self.created_materials = []
 52        Factory.all_factories.append(self)
 53
 54    def __call__(self, *args, **kwargs):
 55        if (not args and not kwargs) or (args and kwargs):
 56            raise ValueError("Как изобщо се стигна до тук???")
 57
 58        if kwargs:
 59            return self.for_kwargs(kwargs)
 60        if args:
 61            return self.for_args(args)
 62
 63    def for_kwargs(self, kwargs):
 64        materials = []
 65        for name, mass in kwargs.items():
 66            if name in material_classes:
 67                material_class = material_classes[name]
 68            elif name in Factory.dynamic_classes:
 69                material_class = Factory.dynamic_classes[name]
 70            else:
 71                raise ValueError(f"Материал с име '{name}' още не измислен глупчо")
 72
 73            material_instance = material_class(mass)
 74            materials.append(material_instance)
 75            self.created_materials.append(material_instance)
 76
 77        return tuple(materials)
 78
 79    def for_args(self, args):
 80        def extract_base_names(materials):
 81            base_names = []
 82
 83            for material in materials:
 84                if "_" in type(material).__name__:
 85                    base_names.extend(type(material).__name__.split("_"))
 86                else:
 87                    base_names.append(type(material).__name__)
 88
 89            return sorted(base_names)
 90
 91        materials = []
 92        for material in args:
 93            if material._used:
 94                raise AssertionError(f"{material} вече е използван да не казвам къде")
 95            material.mark_as_used()
 96            materials.append(material)
 97
 98        class_name = "_".join(extract_base_names(materials))
 99
100        if class_name not in Factory.dynamic_classes:
101            density = sum(type(current_material).density for current_material in materials) / len(materials)
102
103            class Alloy(Material):
104                pass
105
106            Alloy.density = density
107            Alloy.__name__ = class_name
108            Factory.dynamic_classes[class_name] = Alloy
109
110        alloy_class = Factory.dynamic_classes[class_name]
111        total_mass = sum(material.mass for material in materials)
112        alloy_instance = alloy_class(total_mass)
113
114        self.created_materials.append(alloy_instance)
115        return alloy_instance
116
117    def can_build(self, required_volume):
118       
119        total_volume = sum(material.volume for material in self.created_materials if not material._used)
120        return total_volume >= required_volume
121
122    @classmethod
123    def can_build_together(cls, required_volume):
124
125        total_volume = 0
126        for factory in cls.all_factories:
127            total_volume += sum(material.volume for material in factory.created_materials if not material._used)
128
129        return total_volume >= required_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 61, in __call__
return self.for_args(args)
^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 94, in for_args
raise AssertionError(f"{material} вече е използван да не казвам къде")
AssertionError: <solution.Concrete object at 0x792c38ada690> вече е използван да не казвам къде

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

----------------------------------------------------------------------
Ran 10 tests in 0.011s

FAILED (failures=3)

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