Домашни > Another brick in the wall > Решения > Решението на Петър Бончев

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

10 точки общо

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

  1class Material:
  2    MATERIALS = {'Concrete' : 2500, 'Brick' : 2000, 'Stone' : 1600,
  3                    'Wood' : 600, 'Steel' : 7700}
  4
  5    def __init__(self, mass):
  6        self.mass = mass
  7        self.valid = True
  8
  9    def invalidate(self):
 10        self.valid = False
 11
 12    @property
 13    def volume(self):
 14        return self.mass / self.density
 15
 16    @property
 17    def is_valid(self):
 18        return self.valid
 19
 20class Concrete(Material):
 21
 22    def __init__(self, mass):
 23        super().__init__(mass)
 24        self.materials = {'Concrete'}
 25        self.density = Material.MATERIALS[list(self.materials)[0]]
 26
 27class Brick(Material):
 28
 29    def __init__(self, mass):
 30        super().__init__(mass)
 31        self.materials = {'Brick'}
 32        self.density = Material.MATERIALS[list(self.materials)[0]]
 33
 34class Stone(Material):
 35
 36    def __init__(self, mass):
 37        super().__init__(mass)
 38        self.materials = {'Stone'}
 39        self.density = Material.MATERIALS[list(self.materials)[0]]
 40
 41class Wood(Material):
 42
 43    def __init__(self, mass):
 44        super().__init__(mass)
 45        self.materials = {'Wood'}
 46        self.density = Material.MATERIALS[list(self.materials)[0]]
 47
 48class Steel(Material):
 49
 50    def __init__(self, mass):
 51        super().__init__(mass)
 52        self.materials = {'Steel'}
 53        self.density = Material.MATERIALS[list(self.materials)[0]]
 54
 55class Factory:
 56    CREATED_CLASSES = {'Concrete', 'Brick', 'Stone', 'Wood', 'Steel'}
 57    FACTORIES = []
 58
 59    def __init__(self):
 60        self.created_materials = []
 61        Factory.FACTORIES.append(self)
 62
 63    def __call__(self, *args, **kwargs):
 64        if len(args) * len(kwargs) != 0 or len(args) + len(kwargs) == 0:
 65            raise ValueError('We dont need no education')
 66
 67        if len(args):
 68            if not all(arg.is_valid for arg in args):
 69                raise AssertionError('Used material')
 70            new_class = Factory.create_new_class(*args)
 71            mass = 0
 72            for arg in args:
 73                mass += arg.mass
 74
 75            new_material = new_class(mass)
 76            self.created_materials.append(new_material)
 77            return new_material
 78
 79        if len(kwargs):
 80            return self._create_materials(**kwargs)
 81
 82    def can_build(self, required_volume):
 83        return self.total_volume() >= required_volume
 84
 85    def total_volume(self):
 86        volume = 0
 87        for material in self.created_materials:
 88            if material.is_valid:
 89                volume += material.volume
 90        return volume
 91
 92    def _create_materials(self, **kwargs):
 93        created_materials = []
 94        for name, value in kwargs.items():
 95            if name not in Factory.CREATED_CLASSES:
 96                raise ValueError('Invalid class name')
 97            created_materials.append(eval(name)(value))
 98        self.created_materials.extend(created_materials)
 99        return tuple(created_materials)
100
101    @staticmethod
102    def create_new_class(*args):
103        used_materials = set()
104        for arg in args:
105            used_materials.update(arg.materials)
106            arg.invalidate()
107        class_name = '_'.join(sorted(used_materials))
108        if class_name in Factory.CREATED_CLASSES:
109            return globals()[class_name]
110
111        density = 0
112        for material in used_materials:
113            density += Material.MATERIALS[material]
114        density /= len(used_materials)
115
116        new_class = type(
117            class_name,
118            (Material,),
119            {
120                'materials': used_materials,
121                'density': density
122            }
123        )
124
125        globals()[class_name] = new_class
126        Factory.CREATED_CLASSES.add(class_name)
127
128        return new_class
129
130    @staticmethod
131    def can_build_together(required_volume):
132        volume = 0
133        for existing_factory in Factory.FACTORIES:
134            volume += existing_factory.total_volume()
135        return volume >= required_volume

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

OK

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