1class Material:
2 def __init__(self, mass):
3 self.mass = mass
4
5 @property
6 def volume(self):
7 return self.mass / self.density
8
9
10class Concrete(Material):
11 density = 2500
12
13
14class Brick(Material):
15 density = 2000
16
17
18class Stone(Material):
19 density = 1600
20
21
22class Wood(Material):
23 density = 600
24
25
26class Steel(Material):
27 density = 7700
28
29
30class Factory:
31 _base_materials = {
32 "Concrete": Concrete,
33 "Brick": Brick,
34 "Stone": Stone,
35 "Wood": Wood,
36 "Steel": Steel,
37 }
38 _all_materials = {}
39 _invalid = []
40 _state_owned = [] # Hello comrade
41
42 def __init__(self):
43 self.owned = []
44
45 def __call__(self, *args, **kwargs):
46 if not args and not kwargs:
47 raise ValueError("Materiali zabravi")
48 if args and kwargs:
49 raise ValueError("Gosho")
50
51 if kwargs:
52 result = []
53 for name, mass in kwargs.items():
54 if name in Factory._base_materials:
55 material_class = Factory._base_materials[name]
56 elif name in Factory._all_materials:
57 material_class = Factory._all_materials[name]
58 else:
59 raise ValueError("Bratko kakvi sa tezi gluposti")
60
61 material_instance = material_class(mass)
62
63 self.owned.append(material_instance)
64 self._state_owned.append(material_instance)
65
66 Factory._all_materials[name] = material_class
67
68 result.append(material_instance)
69 return tuple(result)
70 else:
71 return self._handle_positional_arguments(args)
72
73 def _handle_positional_arguments(self, args):
74 for arg in args:
75 if arg in Factory._invalid:
76 raise AssertionError("tova si go polzval bot")
77
78 for arg in args:
79 Factory._invalid.append(arg)
80
81 all_class_names = []
82 for arg in args:
83 class_name_parts = arg.__class__.__name__.split("_")
84 all_class_names.extend(class_name_parts)
85 sorted_class_names = sorted(set(all_class_names))
86 class_name = "_".join(sorted_class_names)
87
88 materials = {arg.__class__ for arg in args}
89
90 if class_name in Factory._all_materials:
91 material_class = Factory._all_materials[class_name]
92 mass = sum(arg.mass for arg in args)
93 material_instance = material_class(mass)
94 self.owned.append(material_instance)
95 self._state_owned.append(material_instance)
96
97 else:
98 mass = sum(arg.mass for arg in args)
99
100 sumz = 0
101 for cls in sorted_class_names:
102 sumz += Factory._base_materials[cls].density
103 avg_density = sumz / len(materials)
104
105 DynamicClass = type(class_name, (Material,), {"density": avg_density})
106
107 obj = DynamicClass(mass)
108
109 Factory._all_materials[class_name] = DynamicClass
110 self.owned.append(obj)
111 self._state_owned.append(obj)
112
113 material_instance = obj
114
115 for arg in args:
116 if arg in self.owned:
117 self.owned.remove(arg)
118 self._state_owned.remove(arg)
119
120 return material_instance
121
122 def can_build(self, volume_needed):
123 total_volume = sum(material.volume for material in self.owned)
124 return total_volume >= volume_needed
125
126 @staticmethod
127 def can_build_together(volume_needed):
128 total_volume = sum(material.volume for material in Factory._state_owned)
129 return total_volume >= volume_needed
......F...
======================================================================
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: 4.0625 != 6.77 within 2 places (2.7074999999999996 difference)
----------------------------------------------------------------------
Ran 10 tests in 0.040s
FAILED (failures=1)
26.11.2024 12:49
26.11.2024 12:50
26.11.2024 12:51
26.11.2024 12:53
26.11.2024 12:56