Домашни > Another brick in the wall > Решения > Решението на Георги Георгиев

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

8 точки общо

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

  1class Material:
  2    density = 0
  3    
  4    def __init__(self, mass):
  5        self.mass = mass
  6        self._used = False
  7        
  8
  9    @property
 10    def volume(self):
 11        return self.mass / self.density
 12    
 13    @volume.setter
 14    def volume(self):
 15        self.volume = self.mass / self.density
 16
 17    @classmethod
 18    def all_materials(cls):
 19        return {subclass.__name__: subclass for subclass in cls.__subclasses__()}
 20    
 21    def use(self):
 22        if self._used:
 23            raise AssertionError("произволен текст")
 24        self._used = True
 25
 26    def is_used(self):
 27        if self._used:
 28            raise AssertionError("произволен текст")
 29
 30class Concrete(Material):
 31    density = 2500
 32
 33class Brick(Material):
 34    density = 2000
 35
 36class Stone(Material):
 37    density = 1600
 38
 39class Wood(Material):
 40    density = 600
 41
 42class Steel(Material):
 43    density = 7700
 44
 45class Factory():
 46    _cashed_classes = {}
 47    _all_materials_created = []
 48    def __init__(self):
 49        self._avaluable_materials = []
 50
 51    def __call__(self, *args, **kwargs):
 52        if args and kwargs:
 53            raise ValueError("произволен текст")
 54        if not args and not kwargs:
 55            raise ValueError("произволен текст")
 56        materials = Material.all_materials() 
 57        #Доста необичайно място за това Λ да. 
 58        #Аргументация --> Ако се счупи  | не искам да се вика метода therefore не е най-отгоре. 
 59        #Ще го ползвам 2 пъти therefore декларирам над 2те функционалности които ще го ползват.
 60        #In conclusion седи по средата.
 61        if kwargs and not args:
 62            items = []
 63            for name, mass in kwargs.items():
 64                if name not in materials:
 65                    raise ValueError("произволен текст")
 66                items.append(materials[name](mass)) #Май се влювам в тоя език ... Pause ...
 67            self._avaluable_materials.extend(items)
 68            Factory._all_materials_created.extend(items)
 69            return tuple(items)
 70        elif args and not kwargs:
 71            if not all(isinstance(material, Material) for material in args):
 72                raise ValueError("произволен текст")
 73            for material in args:
 74                material.is_used()
 75            material_names = sorted([material.__class__.__name__ for material in args])
 76            class_name = "_".join(material_names)
 77            if class_name in Factory._cashed_classes:
 78                for material in args:
 79                    material.use()
 80                composite_instance = Factory._cashed_classes[class_name](sum(material.mass for material in args))
 81            else:        
 82                new_density = sum(arg.density for arg in args) / len(args)
 83                new_mass = sum(arg.mass for arg in args)
 84                new_class = type(class_name, (Material,), {"density": new_density, "_used": False})
 85                Factory._cashed_classes[class_name] = new_class
 86                composite_instance = new_class(new_mass)
 87                for material in args:
 88                    material.use()
 89            self._avaluable_materials.append(composite_instance)
 90            Factory._all_materials_created.append(composite_instance)
 91            return composite_instance
 92
 93    def can_build(self, required_mats):
 94        valid_materials = [m for m in self._avaluable_materials if not m._used]
 95        total_volume = sum(m.volume for m in valid_materials)
 96        return total_volume >= required_mats
 97    
 98    @classmethod
 99    def can_build_together(cls, required_mats):
100        valid_materials = [m for m in cls._all_materials_created if not m._used]
101        total_volume = sum(m.volume for m in valid_materials)
102        return total_volume >= required_mats

......FF..
======================================================================
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
? ++++++

======================================================================
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.012s

FAILED (failures=2)

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