1class Material:
2 def __init__(self, mass):
3 self.mass = mass
4 self._used = False
5
6 @property
7 def volume(self):
8 return self.mass / self._density
9
10 def mark_used(self):
11 if self._used:
12 raise AssertionError("Material already used.")
13 self._used = True
14
15
16class Concrete(Material):
17 _density = 2500
18
19
20class Brick(Material):
21 _density = 2000
22
23
24class Stone(Material):
25 _density = 1600
26
27
28class Wood(Material):
29 _density = 600
30
31
32class Steel(Material):
33 _density = 7700
34
35
36class Factory:
37 _registry = { "Concrete": Concrete,
38 "Brick": Brick,
39 "Stone": Stone,
40 "Wood": Wood,
41 "Steel": Steel,}
42
43 _all_factories = []
44
45 def __init__(self):
46 self.materials = []
47 Factory._all_factories.append(self)
48
49 def __call__(self, *args, **kwargs):
50 if args and kwargs:
51 raise ValueError("Cannot mix positional and keyword arguments.")
52 if not args and not kwargs:
53 raise ValueError("Must provide either positional or keyword arguments.")
54
55 if kwargs:
56 return self._handle_named_args(kwargs)
57 else:
58 return self._handle_positional_args(args)
59
60 def _handle_named_args(self, kwargs):
61 results = []
62 for name, mass in kwargs.items():
63 if name not in Factory._registry:
64 raise ValueError(f"Invalid material name: {name}")
65 material_class = Factory._registry[name]
66 instance = material_class(mass)
67 self.materials.append(instance)
68 results.append(instance)
69 return tuple(results)
70
71 def _handle_positional_args(self, args):
72 for material in args:
73 material.mark_used()
74
75 material_classes = []
76 for material in args:
77 if "_" in material.__class__.__name__:
78 material_classes.extend(material.__class__.__name__.split("_"))
79 else:
80 material_classes.append(material.__class__.__name__)
81
82
83 class_name = "_".join(sorted(set(material_classes)))
84
85 if class_name not in Factory._registry:
86 densities = [cls._density for cls in set(type(material) for material in args)]
87 avg_density = sum(densities) / len(densities)
88
89 class DynamicMaterial(Material):
90 _density = avg_density
91
92 DynamicMaterial.__name__ = class_name
93 Factory._registry[class_name] = DynamicMaterial
94
95 new_material_class = Factory._registry[class_name]
96 total_mass = sum(material.mass for material in args)
97 instance = new_material_class(total_mass)
98 self.materials.append(instance)
99 return instance
100
101 def can_build(self, volume):
102 total_volume = sum(material.volume for material in self.materials if not material._used)
103 return total_volume >= volume
104
105 @classmethod
106 def can_build_together(cls, volume):
107 total_volume = sum(
108 material.volume
109 for factory in cls._all_factories
110 for material in factory.materials
111 if not material._used
112 )
113 return total_volume >= volume
.....FF...
======================================================================
FAIL: test_positional_arguments_multiple_argument_from_initial_set (test.TestFactory.test_positional_arguments_multiple_argument_from_initial_set)
Test calling a factory using multiple positional arguments.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 116, in test_positional_arguments_multiple_argument_from_initial_set
concrete_wood = self.factory1(concrete, wood)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 58, in __call__
return self._handle_positional_args(args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 73, in _handle_positional_args
material.mark_used()
File "/tmp/solution.py", line 12, in mark_used
raise AssertionError("Material already used.")
AssertionError: Material already used.
======================================================================
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: 5.661290322580645 != 6.77 within 2 places (1.1087096774193546 difference)
----------------------------------------------------------------------
Ran 10 tests in 0.010s
FAILED (failures=2)
Виктор Бечев
26.11.2024 17:20Отвъд горните дребни забелжки - кодът изглежда добре и се чете прилично.
|
Георги Кунчев
25.11.2024 22:40Качвам решението ръчно поради (все още) незнаен проблем.
|
Виктор Бечев
25.11.2024 22:14Файлът, който си качила е нечетим.
Провери дали случайно не е с грешното разширение (например да си качила някое `.pyc` или нещо подобно).
Освен ако не се опитваш да ни хакнеш сайта, тогава хем не изглежда да е успешно, хем ще получиш 0 точки на домашното. :grin:
|
f | 1 | class Material: | f | 1 | class Material: |
2 | def __init__(self, mass): | 2 | def __init__(self, mass): | ||
3 | self.mass = mass | 3 | self.mass = mass | ||
4 | self._used = False | 4 | self._used = False | ||
5 | 5 | ||||
6 | @property | 6 | @property | ||
7 | def volume(self): | 7 | def volume(self): | ||
8 | return self.mass / self._density | 8 | return self.mass / self._density | ||
9 | 9 | ||||
10 | def mark_used(self): | 10 | def mark_used(self): | ||
11 | if self._used: | 11 | if self._used: | ||
12 | raise AssertionError("Material already used.") | 12 | raise AssertionError("Material already used.") | ||
13 | self._used = True | 13 | self._used = True | ||
14 | 14 | ||||
15 | 15 | ||||
16 | class Concrete(Material): | 16 | class Concrete(Material): | ||
17 | _density = 2500 | 17 | _density = 2500 | ||
18 | 18 | ||||
19 | 19 | ||||
20 | class Brick(Material): | 20 | class Brick(Material): | ||
21 | _density = 2000 | 21 | _density = 2000 | ||
22 | 22 | ||||
23 | 23 | ||||
24 | class Stone(Material): | 24 | class Stone(Material): | ||
25 | _density = 1600 | 25 | _density = 1600 | ||
26 | 26 | ||||
27 | 27 | ||||
28 | class Wood(Material): | 28 | class Wood(Material): | ||
29 | _density = 600 | 29 | _density = 600 | ||
30 | 30 | ||||
31 | 31 | ||||
32 | class Steel(Material): | 32 | class Steel(Material): | ||
33 | _density = 7700 | 33 | _density = 7700 | ||
34 | 34 | ||||
35 | 35 | ||||
36 | class Factory: | 36 | class Factory: | ||
37 | _registry = { "Concrete": Concrete, | 37 | _registry = { "Concrete": Concrete, | ||
38 | "Brick": Brick, | 38 | "Brick": Brick, | ||
39 | "Stone": Stone, | 39 | "Stone": Stone, | ||
40 | "Wood": Wood, | 40 | "Wood": Wood, | ||
41 | "Steel": Steel,} | 41 | "Steel": Steel,} | ||
42 | 42 | ||||
43 | _all_factories = [] | 43 | _all_factories = [] | ||
44 | 44 | ||||
45 | def __init__(self): | 45 | def __init__(self): | ||
46 | self.materials = [] | 46 | self.materials = [] | ||
47 | Factory._all_factories.append(self) | 47 | Factory._all_factories.append(self) | ||
48 | 48 | ||||
49 | def __call__(self, *args, **kwargs): | 49 | def __call__(self, *args, **kwargs): | ||
50 | if args and kwargs: | 50 | if args and kwargs: | ||
51 | raise ValueError("Cannot mix positional and keyword arguments.") | 51 | raise ValueError("Cannot mix positional and keyword arguments.") | ||
52 | if not args and not kwargs: | 52 | if not args and not kwargs: | ||
53 | raise ValueError("Must provide either positional or keyword arguments.") | 53 | raise ValueError("Must provide either positional or keyword arguments.") | ||
54 | 54 | ||||
55 | if kwargs: | 55 | if kwargs: | ||
56 | return self._handle_named_args(kwargs) | 56 | return self._handle_named_args(kwargs) | ||
57 | else: | 57 | else: | ||
58 | return self._handle_positional_args(args) | 58 | return self._handle_positional_args(args) | ||
59 | 59 | ||||
60 | def _handle_named_args(self, kwargs): | 60 | def _handle_named_args(self, kwargs): | ||
61 | results = [] | 61 | results = [] | ||
62 | for name, mass in kwargs.items(): | 62 | for name, mass in kwargs.items(): | ||
63 | if name not in Factory._registry: | 63 | if name not in Factory._registry: | ||
64 | raise ValueError(f"Invalid material name: {name}") | 64 | raise ValueError(f"Invalid material name: {name}") | ||
65 | material_class = Factory._registry[name] | 65 | material_class = Factory._registry[name] | ||
66 | instance = material_class(mass) | 66 | instance = material_class(mass) | ||
67 | self.materials.append(instance) | 67 | self.materials.append(instance) | ||
68 | results.append(instance) | 68 | results.append(instance) | ||
69 | return tuple(results) | 69 | return tuple(results) | ||
70 | 70 | ||||
71 | def _handle_positional_args(self, args): | 71 | def _handle_positional_args(self, args): | ||
72 | for material in args: | 72 | for material in args: | ||
73 | material.mark_used() | 73 | material.mark_used() | ||
74 | 74 | ||||
n | 75 | material_classes = sorted(set(type(material) for material in args), key=lambda cls: cls.__name__) | n | 75 | material_classes = [] |
76 | for material in args: | ||||
77 | if "_" in material.__class__.__name__: | ||||
78 | material_classes.extend(material.__class__.__name__.split("_")) | ||||
79 | else: | ||||
80 | material_classes.append(material.__class__.__name__) | ||||
81 | |||||
82 | |||||
76 | class_name = "_".join(sorted(cls.__name__ for cls in material_classes)) | 83 | class_name = "_".join(sorted(set(material_classes))) | ||
77 | 84 | ||||
78 | if class_name not in Factory._registry: | 85 | if class_name not in Factory._registry: | ||
n | 79 | densities = [cls._density for cls in material_classes] | n | 86 | densities = [cls._density for cls in set(type(material) for material in args)] |
80 | avg_density = sum(densities) / len(densities) | 87 | avg_density = sum(densities) / len(densities) | ||
81 | 88 | ||||
82 | class DynamicMaterial(Material): | 89 | class DynamicMaterial(Material): | ||
83 | _density = avg_density | 90 | _density = avg_density | ||
84 | 91 | ||||
85 | DynamicMaterial.__name__ = class_name | 92 | DynamicMaterial.__name__ = class_name | ||
86 | Factory._registry[class_name] = DynamicMaterial | 93 | Factory._registry[class_name] = DynamicMaterial | ||
87 | 94 | ||||
88 | new_material_class = Factory._registry[class_name] | 95 | new_material_class = Factory._registry[class_name] | ||
89 | total_mass = sum(material.mass for material in args) | 96 | total_mass = sum(material.mass for material in args) | ||
90 | instance = new_material_class(total_mass) | 97 | instance = new_material_class(total_mass) | ||
91 | self.materials.append(instance) | 98 | self.materials.append(instance) | ||
92 | return instance | 99 | return instance | ||
93 | 100 | ||||
94 | def can_build(self, volume): | 101 | def can_build(self, volume): | ||
95 | total_volume = sum(material.volume for material in self.materials if not material._used) | 102 | total_volume = sum(material.volume for material in self.materials if not material._used) | ||
96 | return total_volume >= volume | 103 | return total_volume >= volume | ||
97 | 104 | ||||
98 | @classmethod | 105 | @classmethod | ||
99 | def can_build_together(cls, volume): | 106 | def can_build_together(cls, volume): | ||
100 | total_volume = sum( | 107 | total_volume = sum( | ||
101 | material.volume | 108 | material.volume | ||
102 | for factory in cls._all_factories | 109 | for factory in cls._all_factories | ||
103 | for material in factory.materials | 110 | for material in factory.materials | ||
104 | if not material._used | 111 | if not material._used | ||
105 | ) | 112 | ) | ||
106 | return total_volume >= volume | 113 | return total_volume >= volume | ||
107 | 114 | ||||
t | t | 115 |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|
f | 1 | class Material: | f | 1 | class Material: |
2 | def __init__(self, mass): | 2 | def __init__(self, mass): | ||
3 | self.mass = mass | 3 | self.mass = mass | ||
n | 4 | self._used = False | n | 4 | self._used = False |
5 | 5 | ||||
6 | @property | 6 | @property | ||
7 | def volume(self): | 7 | def volume(self): | ||
8 | return self.mass / self._density | 8 | return self.mass / self._density | ||
9 | 9 | ||||
10 | def mark_used(self): | 10 | def mark_used(self): | ||
11 | if self._used: | 11 | if self._used: | ||
12 | raise AssertionError("Material already used.") | 12 | raise AssertionError("Material already used.") | ||
13 | self._used = True | 13 | self._used = True | ||
14 | 14 | ||||
15 | 15 | ||||
16 | class Concrete(Material): | 16 | class Concrete(Material): | ||
17 | _density = 2500 | 17 | _density = 2500 | ||
18 | 18 | ||||
19 | 19 | ||||
20 | class Brick(Material): | 20 | class Brick(Material): | ||
21 | _density = 2000 | 21 | _density = 2000 | ||
22 | 22 | ||||
23 | 23 | ||||
24 | class Stone(Material): | 24 | class Stone(Material): | ||
25 | _density = 1600 | 25 | _density = 1600 | ||
26 | 26 | ||||
27 | 27 | ||||
28 | class Wood(Material): | 28 | class Wood(Material): | ||
29 | _density = 600 | 29 | _density = 600 | ||
30 | 30 | ||||
31 | 31 | ||||
32 | class Steel(Material): | 32 | class Steel(Material): | ||
33 | _density = 7700 | 33 | _density = 7700 | ||
34 | 34 | ||||
35 | 35 | ||||
36 | class Factory: | 36 | class Factory: | ||
37 | _registry = { "Concrete": Concrete, | 37 | _registry = { "Concrete": Concrete, | ||
38 | "Brick": Brick, | 38 | "Brick": Brick, | ||
39 | "Stone": Stone, | 39 | "Stone": Stone, | ||
40 | "Wood": Wood, | 40 | "Wood": Wood, | ||
41 | "Steel": Steel,} | 41 | "Steel": Steel,} | ||
42 | 42 | ||||
43 | _all_factories = [] | 43 | _all_factories = [] | ||
44 | 44 | ||||
45 | def __init__(self): | 45 | def __init__(self): | ||
46 | self.materials = [] | 46 | self.materials = [] | ||
47 | Factory._all_factories.append(self) | 47 | Factory._all_factories.append(self) | ||
48 | 48 | ||||
n | 49 | def __call__(self, *args, **kwargs): | n | 49 | def __call__(self, *args, **kwargs): |
50 | if args and kwargs: | 50 | if args and kwargs: | ||
51 | raise ValueError("Cannot mix positional and keyword arguments.") | 51 | raise ValueError("Cannot mix positional and keyword arguments.") | ||
52 | if not args and not kwargs: | 52 | if not args and not kwargs: | ||
53 | raise ValueError("Must provide either positional or keyword arguments.") | 53 | raise ValueError("Must provide either positional or keyword arguments.") | ||
54 | 54 | ||||
55 | if kwargs: | 55 | if kwargs: | ||
56 | return self._handle_named_args(kwargs) | 56 | return self._handle_named_args(kwargs) | ||
57 | else: | 57 | else: | ||
58 | return self._handle_positional_args(args) | 58 | return self._handle_positional_args(args) | ||
59 | 59 | ||||
60 | def _handle_named_args(self, kwargs): | 60 | def _handle_named_args(self, kwargs): | ||
61 | results = [] | 61 | results = [] | ||
62 | for name, mass in kwargs.items(): | 62 | for name, mass in kwargs.items(): | ||
63 | if name not in Factory._registry: | 63 | if name not in Factory._registry: | ||
64 | raise ValueError(f"Invalid material name: {name}") | 64 | raise ValueError(f"Invalid material name: {name}") | ||
65 | material_class = Factory._registry[name] | 65 | material_class = Factory._registry[name] | ||
66 | instance = material_class(mass) | 66 | instance = material_class(mass) | ||
67 | self.materials.append(instance) | 67 | self.materials.append(instance) | ||
68 | results.append(instance) | 68 | results.append(instance) | ||
69 | return tuple(results) | 69 | return tuple(results) | ||
70 | 70 | ||||
71 | def _handle_positional_args(self, args): | 71 | def _handle_positional_args(self, args): | ||
72 | for material in args: | 72 | for material in args: | ||
73 | material.mark_used() | 73 | material.mark_used() | ||
74 | 74 | ||||
75 | material_classes = sorted(set(type(material) for material in args), key=lambda cls: cls.__name__) | 75 | material_classes = sorted(set(type(material) for material in args), key=lambda cls: cls.__name__) | ||
76 | class_name = "_".join(sorted(cls.__name__ for cls in material_classes)) | 76 | class_name = "_".join(sorted(cls.__name__ for cls in material_classes)) | ||
77 | 77 | ||||
78 | if class_name not in Factory._registry: | 78 | if class_name not in Factory._registry: | ||
79 | densities = [cls._density for cls in material_classes] | 79 | densities = [cls._density for cls in material_classes] | ||
80 | avg_density = sum(densities) / len(densities) | 80 | avg_density = sum(densities) / len(densities) | ||
81 | 81 | ||||
82 | class DynamicMaterial(Material): | 82 | class DynamicMaterial(Material): | ||
83 | _density = avg_density | 83 | _density = avg_density | ||
84 | 84 | ||||
85 | DynamicMaterial.__name__ = class_name | 85 | DynamicMaterial.__name__ = class_name | ||
86 | Factory._registry[class_name] = DynamicMaterial | 86 | Factory._registry[class_name] = DynamicMaterial | ||
87 | 87 | ||||
88 | new_material_class = Factory._registry[class_name] | 88 | new_material_class = Factory._registry[class_name] | ||
89 | total_mass = sum(material.mass for material in args) | 89 | total_mass = sum(material.mass for material in args) | ||
90 | instance = new_material_class(total_mass) | 90 | instance = new_material_class(total_mass) | ||
91 | self.materials.append(instance) | 91 | self.materials.append(instance) | ||
92 | return instance | 92 | return instance | ||
93 | 93 | ||||
94 | def can_build(self, volume): | 94 | def can_build(self, volume): | ||
95 | total_volume = sum(material.volume for material in self.materials if not material._used) | 95 | total_volume = sum(material.volume for material in self.materials if not material._used) | ||
96 | return total_volume >= volume | 96 | return total_volume >= volume | ||
97 | 97 | ||||
98 | @classmethod | 98 | @classmethod | ||
99 | def can_build_together(cls, volume): | 99 | def can_build_together(cls, volume): | ||
100 | total_volume = sum( | 100 | total_volume = sum( | ||
101 | material.volume | 101 | material.volume | ||
n | 102 | for factory in cls._all_factories | n | 102 | for factory in cls._all_factories |
103 | for material in factory.materials | 103 | for material in factory.materials | ||
104 | if not material._used | 104 | if not material._used | ||
105 | ) | 105 | ) | ||
106 | return total_volume >= volume | 106 | return total_volume >= volume | ||
107 | 107 | ||||
t | 108 | factory = Factory() | t | ||
109 | brick, wood = factory(Brick=10, Wood=5) | ||||
110 | concreate, = factory(Concrete=10) | ||||
111 | brick_wood = factory(brick, wood) | ||||
112 | |||||
113 | another_brick_wood, = factory(Brick_Wood=10) # Валидно инстанциране на ново парче сплав с маса 10 и тип Brick_Wood, който е създаден на предишния ред | ||||
114 | |||||
115 | brick_concrete_wood = factory(brick_wood, concreate) |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|
f | 1 | class Material: | f | 1 | class Material: |
2 | def __init__(self, mass): | 2 | def __init__(self, mass): | ||
3 | self.mass = mass | 3 | self.mass = mass | ||
n | 4 | self._used = False | n | 4 | self._used = False |
5 | 5 | ||||
6 | @property | 6 | @property | ||
7 | def volume(self): | 7 | def volume(self): | ||
8 | return self.mass / self._density | 8 | return self.mass / self._density | ||
9 | 9 | ||||
10 | def mark_used(self): | 10 | def mark_used(self): | ||
11 | if self._used: | 11 | if self._used: | ||
12 | raise AssertionError("Material already used.") | 12 | raise AssertionError("Material already used.") | ||
13 | self._used = True | 13 | self._used = True | ||
14 | 14 | ||||
15 | 15 | ||||
16 | class Concrete(Material): | 16 | class Concrete(Material): | ||
17 | _density = 2500 | 17 | _density = 2500 | ||
18 | 18 | ||||
19 | 19 | ||||
20 | class Brick(Material): | 20 | class Brick(Material): | ||
21 | _density = 2000 | 21 | _density = 2000 | ||
22 | 22 | ||||
23 | 23 | ||||
24 | class Stone(Material): | 24 | class Stone(Material): | ||
25 | _density = 1600 | 25 | _density = 1600 | ||
26 | 26 | ||||
27 | 27 | ||||
28 | class Wood(Material): | 28 | class Wood(Material): | ||
29 | _density = 600 | 29 | _density = 600 | ||
30 | 30 | ||||
31 | 31 | ||||
32 | class Steel(Material): | 32 | class Steel(Material): | ||
33 | _density = 7700 | 33 | _density = 7700 | ||
34 | 34 | ||||
35 | 35 | ||||
36 | class Factory: | 36 | class Factory: | ||
37 | _registry = { "Concrete": Concrete, | 37 | _registry = { "Concrete": Concrete, | ||
38 | "Brick": Brick, | 38 | "Brick": Brick, | ||
39 | "Stone": Stone, | 39 | "Stone": Stone, | ||
40 | "Wood": Wood, | 40 | "Wood": Wood, | ||
41 | "Steel": Steel,} | 41 | "Steel": Steel,} | ||
42 | 42 | ||||
43 | _all_factories = [] | 43 | _all_factories = [] | ||
44 | 44 | ||||
45 | def __init__(self): | 45 | def __init__(self): | ||
46 | self.materials = [] | 46 | self.materials = [] | ||
47 | Factory._all_factories.append(self) | 47 | Factory._all_factories.append(self) | ||
48 | 48 | ||||
n | 49 | def __call__(self, *args, **kwargs): | n | 49 | def __call__(self, *args, **kwargs): |
50 | if args and kwargs: | 50 | if args and kwargs: | ||
51 | raise ValueError("Cannot mix positional and keyword arguments.") | 51 | raise ValueError("Cannot mix positional and keyword arguments.") | ||
52 | if not args and not kwargs: | 52 | if not args and not kwargs: | ||
53 | raise ValueError("Must provide either positional or keyword arguments.") | 53 | raise ValueError("Must provide either positional or keyword arguments.") | ||
54 | 54 | ||||
55 | if kwargs: | 55 | if kwargs: | ||
56 | return self._handle_named_args(kwargs) | 56 | return self._handle_named_args(kwargs) | ||
57 | else: | 57 | else: | ||
58 | return self._handle_positional_args(args) | 58 | return self._handle_positional_args(args) | ||
59 | 59 | ||||
60 | def _handle_named_args(self, kwargs): | 60 | def _handle_named_args(self, kwargs): | ||
61 | results = [] | 61 | results = [] | ||
62 | for name, mass in kwargs.items(): | 62 | for name, mass in kwargs.items(): | ||
63 | if name not in Factory._registry: | 63 | if name not in Factory._registry: | ||
64 | raise ValueError(f"Invalid material name: {name}") | 64 | raise ValueError(f"Invalid material name: {name}") | ||
65 | material_class = Factory._registry[name] | 65 | material_class = Factory._registry[name] | ||
66 | instance = material_class(mass) | 66 | instance = material_class(mass) | ||
67 | self.materials.append(instance) | 67 | self.materials.append(instance) | ||
68 | results.append(instance) | 68 | results.append(instance) | ||
69 | return tuple(results) | 69 | return tuple(results) | ||
70 | 70 | ||||
71 | def _handle_positional_args(self, args): | 71 | def _handle_positional_args(self, args): | ||
72 | for material in args: | 72 | for material in args: | ||
73 | material.mark_used() | 73 | material.mark_used() | ||
74 | 74 | ||||
75 | material_classes = sorted(set(type(material) for material in args), key=lambda cls: cls.__name__) | 75 | material_classes = sorted(set(type(material) for material in args), key=lambda cls: cls.__name__) | ||
76 | class_name = "_".join(sorted(cls.__name__ for cls in material_classes)) | 76 | class_name = "_".join(sorted(cls.__name__ for cls in material_classes)) | ||
77 | 77 | ||||
78 | if class_name not in Factory._registry: | 78 | if class_name not in Factory._registry: | ||
79 | densities = [cls._density for cls in material_classes] | 79 | densities = [cls._density for cls in material_classes] | ||
80 | avg_density = sum(densities) / len(densities) | 80 | avg_density = sum(densities) / len(densities) | ||
81 | 81 | ||||
82 | class DynamicMaterial(Material): | 82 | class DynamicMaterial(Material): | ||
83 | _density = avg_density | 83 | _density = avg_density | ||
84 | 84 | ||||
85 | DynamicMaterial.__name__ = class_name | 85 | DynamicMaterial.__name__ = class_name | ||
86 | Factory._registry[class_name] = DynamicMaterial | 86 | Factory._registry[class_name] = DynamicMaterial | ||
87 | 87 | ||||
88 | new_material_class = Factory._registry[class_name] | 88 | new_material_class = Factory._registry[class_name] | ||
89 | total_mass = sum(material.mass for material in args) | 89 | total_mass = sum(material.mass for material in args) | ||
90 | instance = new_material_class(total_mass) | 90 | instance = new_material_class(total_mass) | ||
91 | self.materials.append(instance) | 91 | self.materials.append(instance) | ||
92 | return instance | 92 | return instance | ||
93 | 93 | ||||
94 | def can_build(self, volume): | 94 | def can_build(self, volume): | ||
95 | total_volume = sum(material.volume for material in self.materials if not material._used) | 95 | total_volume = sum(material.volume for material in self.materials if not material._used) | ||
96 | return total_volume >= volume | 96 | return total_volume >= volume | ||
97 | 97 | ||||
98 | @classmethod | 98 | @classmethod | ||
99 | def can_build_together(cls, volume): | 99 | def can_build_together(cls, volume): | ||
100 | total_volume = sum( | 100 | total_volume = sum( | ||
101 | material.volume | 101 | material.volume | ||
n | 102 | for factory in cls._all_factories | n | 102 | for factory in cls._all_factories |
103 | for material in factory.materials | 103 | for material in factory.materials | ||
104 | if not material._used | 104 | if not material._used | ||
105 | ) | 105 | ) | ||
106 | return total_volume >= volume | 106 | return total_volume >= volume | ||
107 | 107 | ||||
108 | factory = Factory() | 108 | factory = Factory() | ||
109 | brick, wood = factory(Brick=10, Wood=5) | 109 | brick, wood = factory(Brick=10, Wood=5) | ||
110 | concreate, = factory(Concrete=10) | 110 | concreate, = factory(Concrete=10) | ||
111 | brick_wood = factory(brick, wood) | 111 | brick_wood = factory(brick, wood) | ||
112 | 112 | ||||
113 | another_brick_wood, = factory(Brick_Wood=10) # Валидно инстанциране на ново парче сплав с маса 10 и тип Brick_Wood, който е създаден на предишния ред | 113 | another_brick_wood, = factory(Brick_Wood=10) # Валидно инстанциране на ново парче сплав с маса 10 и тип Brick_Wood, който е създаден на предишния ред | ||
114 | 114 | ||||
t | 115 | brick_concrete_wood = factory(brick_wood, concreate) | t | 115 | brick_concrete_wood = factory(brick_wood, concreate) |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|
26.11.2024 16:51
26.11.2024 16:53