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

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

7 точки общо

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

  1class Concrete:
  2    density = 2500
  3
  4    def __init__(self, mass):
  5        self.mass = mass
  6
  7    @property
  8    def volume(self):
  9        return self.mass / self.density
 10
 11
 12class Brick:
 13    density = 2000
 14
 15    def __init__(self, mass):
 16        self.mass = mass
 17
 18    @property
 19    def volume(self):
 20        return self.mass / self.density
 21
 22
 23class Stone:
 24    density = 1600
 25
 26    def __init__(self, mass):
 27        self.mass = mass
 28
 29    @property
 30    def volume(self):
 31        return self.mass / self.density
 32
 33
 34class Wood:
 35    density = 600
 36
 37    def __init__(self, mass):
 38        self.mass = mass
 39
 40    @property
 41    def volume(self):
 42        return self.mass / self.density
 43
 44
 45class Steel:
 46    density = 7700
 47
 48    def __init__(self, mass):
 49        self.mass = mass
 50
 51    @property
 52    def volume(self):
 53        return self.mass / self.density
 54
 55
 56class Factory:
 57    global_materials_dict = {cls.__name__: cls for cls in [Concrete, Brick, Stone, Wood, Steel]}
 58    all_created_objects = []
 59    
 60    def __init__(self):
 61        self.materials_dict = Factory.global_materials_dict.copy()
 62
 63        self.used_objects = set()
 64
 65        self.created_objects = []
 66
 67        Factory.all_created_objects.append(self.created_objects)
 68
 69    def __call__(self, *args, **kwargs):
 70        if args and kwargs:
 71            raise ValueError("Do not mix positional and keyword arguments.")
 72        
 73        if not args and not kwargs:
 74            raise ValueError("Must be called with arguments.")
 75        
 76        if kwargs:
 77            result = []
 78
 79            for name, mass in kwargs.items():
 80                if name not in self.materials_dict:
 81                    raise ValueError(f"Unknown material: {name}")
 82                
 83                material_class = self.materials_dict[name]
 84                
 85                obj = material_class(mass)
 86                
 87                self.created_objects.append(obj)
 88                result.append(obj)
 89
 90            return tuple(result)
 91
 92        if args:
 93            base_materials = set()
 94            total_mass = 0
 95
 96            for material in args:
 97                if material in self.used_objects:
 98                    raise AssertionError("Material has already been used.")
 99                
100                arg_class_name = material.__class__.__name__
101
102                base_materials.add(arg_class_name)
103                
104                total_mass += material.mass
105
106            self.used_objects.update(args)
107
108            class_name = "_".join(sorted(base_materials))
109            
110            if class_name not in Factory.global_materials_dict:
111                if arg_class_name not in self.materials_dict:
112                    return
113
114                average_density = sum(self.materials_dict[name].density for name in base_materials) / len(base_materials)
115
116                new_class = type(
117                    class_name,
118                    (object,),
119                    {
120                        "density": average_density,
121                        "__init__": lambda self, mass: setattr(self, "mass", mass),
122                        "volume": property(lambda self: self.mass / self.density),
123                    },
124                )
125
126                Factory.global_materials_dict[class_name] = new_class
127                
128                self.materials_dict[class_name] = new_class
129
130            obj = self.materials_dict[class_name](total_mass)
131            
132            self.created_objects.append(obj)
133            
134            return obj
135
136    def can_build(self, required_volume):
137        total_volume = sum(obj.volume for obj in self.created_objects)
138        
139        return total_volume >= required_volume
140
141    @classmethod
142    def can_build_together(cls, required_volume):
143        total_volume = sum(obj.volume for created_objects in cls.all_created_objects for obj in created_objects)
144        
145        return total_volume >= required_volume

.FE...F...
======================================================================
ERROR: test_materials_between_factories (test.TestFactory.test_materials_between_factories)
Test materials sharing.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 156, in test_materials_between_factories
result2, = self.factory2(Brick_Concrete_Steel_Stone_Wood=2)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 81, in __call__
raise ValueError(f"Unknown material: {name}")
ValueError: Unknown material: Brick_Concrete_Steel_Stone_Wood

======================================================================
FAIL: test_can_build (test.TestFactory.test_can_build)
Test can_build methods.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 175, in test_can_build
self.assertFalse(self.factory2.can_build(4.0001))
AssertionError: True is not false

======================================================================
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: 'Brick_Concrete_Stone_Steel_Wood' != 'Brick_Concrete_Steel_Stone_Wood'
- Brick_Concrete_Stone_Steel_Wood
? ------
+ Brick_Concrete_Steel_Stone_Wood
? ++++++

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

FAILED (failures=2, errors=1)

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