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
26.11.2024 14:28
26.11.2024 14:29
26.11.2024 14:31
26.11.2024 14:33
26.11.2024 14:33
26.11.2024 14:34
26.11.2024 14:37
26.11.2024 14:35
26.11.2024 14:36