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
11class Concrete(Material):
12 density = 2500
13
14
15class Brick(Material):
16 density = 2000
17
18
19class Stone(Material):
20 density = 1600
21
22
23class Wood(Material):
24 density = 600
25
26
27class Steel(Material):
28 density = 7700
29
30
31class Factory:
32 all_factories = []
33
34 known_materials = {
35 'Concrete': Concrete,
36 'Brick': Brick,
37 'Stone': Stone,
38 'Wood': Wood,
39 'Steel': Steel
40 }
41
42 def __init__(self):
43 self.created = []
44 Factory.all_factories.append(self)
45
46 def __call__(self, *args, **kargs):
47 """This method is not long, it's monumental."""
48 if args and kargs or not args and not kargs:
49 raise ValueError
50
51 if kargs:
52 result = []
53 for material_name, mass in kargs.items():
54 if material_name not in Factory.known_materials:
55 raise ValueError(f"Unknown material: {material_name}")
56
57 material = Factory.known_materials[material_name]
58 self.created.append(Factory.known_materials[material_name](mass))
59 result.append(material(mass))
60
61 return tuple(result)
62
63 if args:
64 for material in args:
65 if material.__class__.__name__ not in Factory.known_materials:
66 raise ValueError(f"Unknown material: {material_name}")
67
68 for material in args:
69 if material.used:
70 raise AssertionError
71
72 for material in args:
73 material.used = True
74
75 for material in self.created:
76 for names in args:
77 if material.__class__.__name__ is names.__class__.__name__:
78 material.used = True
79
80 material_name = []
81
82 for material in args:
83 material_name.append(material.__class__.__name__)
84
85 new_material_name = '_'.join(material_name)
86
87 material_mass = sum(material.mass for material in args)
88
89 if new_material_name in Factory.known_materials:
90 self.created.append(Factory.known_materials[new_material_name](material_mass))
91 return Factory.known_materials[new_material_name](material_mass)
92
93 original_materials_names = new_material_name.split('_')
94
95 material_density = 0
96 for material in original_materials_names:
97 material_density += Factory.known_materials[material].density
98
99 material_density /= len(original_materials_names)
100
101 new_material = type(new_material_name, (Material,), {
102 'density': material_density,
103 })
104
105 Factory.known_materials[new_material_name] = new_material
106 self.created.append(Factory.known_materials[new_material_name](material_mass))
107
108 return new_material(material_mass)
109
110 def get_total_volume(self):
111 total_volume = 0
112 for materials in self.created:
113 if materials.used is False:
114 total_volume += materials.volume
115 return total_volume
116
117 def can_build(self, volume_needed):
118 return self.get_total_volume() >= volume_needed
119
120 @classmethod
121 def can_build_together(cls, volume_needed):
122 total_volume = 0
123
124 for factories in cls.all_factories:
125 total_volume += factories.get_total_volume()
126 return total_volume >= volume_needed
..E.EFF...
======================================================================
ERROR: test_materials_between_factories (test.TestFactory.test_materials_between_factories)
Test materials sharing.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 156, in test_materials_between_factories
result2, = self.factory2(Brick_Concrete_Steel_Stone_Wood=2)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 55, in __call__
raise ValueError(f"Unknown material: {material_name}")
ValueError: Unknown material: Brick_Concrete_Steel_Stone_Wood
======================================================================
ERROR: test_named_arguments_with_dynamically_created_classes (test.TestFactory.test_named_arguments_with_dynamically_created_classes)
Test dynamically created classes uniqueness.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 145, in test_named_arguments_with_dynamically_created_classes
result2, = self.factory1(Brick_Concrete_Steel_Stone_Wood=2)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 55, in __call__
raise ValueError(f"Unknown material: {material_name}")
ValueError: Unknown material: Brick_Concrete_Steel_Stone_Wood
======================================================================
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 94, in test_positional_arguments_multiple_argument_from_initial_set
self.assertEqual(result.__class__.__name__, 'Brick_Concrete_Wood')
AssertionError: 'Wood_Brick_Concrete' != 'Brick_Concrete_Wood'
- Wood_Brick_Concrete
? -----
+ Brick_Concrete_Wood
? +++++
======================================================================
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: 'Steel_Stone_Concrete_Brick_Wood' != 'Brick_Concrete_Steel_Stone_Wood'
- Steel_Stone_Concrete_Brick_Wood
+ Brick_Concrete_Steel_Stone_Wood
----------------------------------------------------------------------
Ran 10 tests in 0.010s
FAILED (failures=2, errors=2)
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 | 10 | ||||
11 | class Concrete(Material): | 11 | class Concrete(Material): | ||
12 | density = 2500 | 12 | density = 2500 | ||
13 | 13 | ||||
14 | 14 | ||||
15 | class Brick(Material): | 15 | class Brick(Material): | ||
16 | density = 2000 | 16 | density = 2000 | ||
17 | 17 | ||||
18 | 18 | ||||
19 | class Stone(Material): | 19 | class Stone(Material): | ||
20 | density = 1600 | 20 | density = 1600 | ||
21 | 21 | ||||
22 | 22 | ||||
23 | class Wood(Material): | 23 | class Wood(Material): | ||
24 | density = 600 | 24 | density = 600 | ||
25 | 25 | ||||
26 | 26 | ||||
27 | class Steel(Material): | 27 | class Steel(Material): | ||
28 | density = 7700 | 28 | density = 7700 | ||
29 | 29 | ||||
30 | 30 | ||||
31 | class Factory: | 31 | class Factory: | ||
32 | all_factories = [] | 32 | all_factories = [] | ||
33 | 33 | ||||
34 | known_materials = { | 34 | known_materials = { | ||
35 | 'Concrete': Concrete, | 35 | 'Concrete': Concrete, | ||
36 | 'Brick': Brick, | 36 | 'Brick': Brick, | ||
37 | 'Stone': Stone, | 37 | 'Stone': Stone, | ||
38 | 'Wood': Wood, | 38 | 'Wood': Wood, | ||
39 | 'Steel': Steel | 39 | 'Steel': Steel | ||
40 | } | 40 | } | ||
41 | 41 | ||||
42 | def __init__(self): | 42 | def __init__(self): | ||
43 | self.created = [] | 43 | self.created = [] | ||
44 | Factory.all_factories.append(self) | 44 | Factory.all_factories.append(self) | ||
45 | 45 | ||||
46 | def __call__(self, *args, **kargs): | 46 | def __call__(self, *args, **kargs): | ||
47 | """This method is not long, it's monumental.""" | 47 | """This method is not long, it's monumental.""" | ||
48 | if args and kargs or not args and not kargs: | 48 | if args and kargs or not args and not kargs: | ||
49 | raise ValueError | 49 | raise ValueError | ||
50 | 50 | ||||
51 | if kargs: | 51 | if kargs: | ||
52 | result = [] | 52 | result = [] | ||
53 | for material_name, mass in kargs.items(): | 53 | for material_name, mass in kargs.items(): | ||
54 | if material_name not in Factory.known_materials: | 54 | if material_name not in Factory.known_materials: | ||
55 | raise ValueError(f"Unknown material: {material_name}") | 55 | raise ValueError(f"Unknown material: {material_name}") | ||
56 | 56 | ||||
57 | material = Factory.known_materials[material_name] | 57 | material = Factory.known_materials[material_name] | ||
58 | self.created.append(Factory.known_materials[material_name](mass)) | 58 | self.created.append(Factory.known_materials[material_name](mass)) | ||
59 | result.append(material(mass)) | 59 | result.append(material(mass)) | ||
60 | 60 | ||||
61 | return tuple(result) | 61 | return tuple(result) | ||
62 | 62 | ||||
63 | if args: | 63 | if args: | ||
64 | for material in args: | 64 | for material in args: | ||
65 | if material.__class__.__name__ not in Factory.known_materials: | 65 | if material.__class__.__name__ not in Factory.known_materials: | ||
66 | raise ValueError(f"Unknown material: {material_name}") | 66 | raise ValueError(f"Unknown material: {material_name}") | ||
67 | 67 | ||||
68 | for material in args: | 68 | for material in args: | ||
69 | if material.used: | 69 | if material.used: | ||
70 | raise AssertionError | 70 | raise AssertionError | ||
71 | 71 | ||||
72 | for material in args: | 72 | for material in args: | ||
73 | material.used = True | 73 | material.used = True | ||
74 | 74 | ||||
75 | for material in self.created: | 75 | for material in self.created: | ||
76 | for names in args: | 76 | for names in args: | ||
77 | if material.__class__.__name__ is names.__class__.__name__: | 77 | if material.__class__.__name__ is names.__class__.__name__: | ||
78 | material.used = True | 78 | material.used = True | ||
79 | 79 | ||||
80 | material_name = [] | 80 | material_name = [] | ||
81 | 81 | ||||
82 | for material in args: | 82 | for material in args: | ||
83 | material_name.append(material.__class__.__name__) | 83 | material_name.append(material.__class__.__name__) | ||
84 | 84 | ||||
85 | new_material_name = '_'.join(material_name) | 85 | new_material_name = '_'.join(material_name) | ||
86 | 86 | ||||
87 | material_mass = sum(material.mass for material in args) | 87 | material_mass = sum(material.mass for material in args) | ||
88 | 88 | ||||
89 | if new_material_name in Factory.known_materials: | 89 | if new_material_name in Factory.known_materials: | ||
90 | self.created.append(Factory.known_materials[new_material_name](material_mass)) | 90 | self.created.append(Factory.known_materials[new_material_name](material_mass)) | ||
91 | return Factory.known_materials[new_material_name](material_mass) | 91 | return Factory.known_materials[new_material_name](material_mass) | ||
92 | 92 | ||||
93 | original_materials_names = new_material_name.split('_') | 93 | original_materials_names = new_material_name.split('_') | ||
94 | 94 | ||||
95 | material_density = 0 | 95 | material_density = 0 | ||
96 | for material in original_materials_names: | 96 | for material in original_materials_names: | ||
97 | material_density += Factory.known_materials[material].density | 97 | material_density += Factory.known_materials[material].density | ||
98 | 98 | ||||
99 | material_density /= len(original_materials_names) | 99 | material_density /= len(original_materials_names) | ||
100 | 100 | ||||
101 | new_material = type(new_material_name, (Material,), { | 101 | new_material = type(new_material_name, (Material,), { | ||
102 | 'density': material_density, | 102 | 'density': material_density, | ||
103 | }) | 103 | }) | ||
104 | 104 | ||||
105 | Factory.known_materials[new_material_name] = new_material | 105 | Factory.known_materials[new_material_name] = new_material | ||
106 | self.created.append(Factory.known_materials[new_material_name](material_mass)) | 106 | self.created.append(Factory.known_materials[new_material_name](material_mass)) | ||
107 | 107 | ||||
108 | return new_material(material_mass) | 108 | return new_material(material_mass) | ||
109 | 109 | ||||
110 | def get_total_volume(self): | 110 | def get_total_volume(self): | ||
111 | total_volume = 0 | 111 | total_volume = 0 | ||
112 | for materials in self.created: | 112 | for materials in self.created: | ||
113 | if materials.used is False: | 113 | if materials.used is False: | ||
114 | total_volume += materials.volume | 114 | total_volume += materials.volume | ||
115 | return total_volume | 115 | return total_volume | ||
116 | 116 | ||||
117 | def can_build(self, volume_needed): | 117 | def can_build(self, volume_needed): | ||
118 | return self.get_total_volume() >= volume_needed | 118 | return self.get_total_volume() >= volume_needed | ||
119 | 119 | ||||
120 | @classmethod | 120 | @classmethod | ||
121 | def can_build_together(cls, volume_needed): | 121 | def can_build_together(cls, volume_needed): | ||
122 | total_volume = 0 | 122 | total_volume = 0 | ||
123 | 123 | ||||
t | 124 | for cur in range(0, len(cls.all_factories)): | t | 124 | for factories in cls.all_factories: |
125 | total_volume += cls.all_factories[cur].get_total_volume() | 125 | total_volume += factories.get_total_volume() | ||
126 | return total_volume >= volume_needed | 126 | return total_volume >= volume_needed |
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 | ||
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 | 10 | ||||
11 | class Concrete(Material): | 11 | class Concrete(Material): | ||
12 | density = 2500 | 12 | density = 2500 | ||
13 | 13 | ||||
14 | 14 | ||||
15 | class Brick(Material): | 15 | class Brick(Material): | ||
16 | density = 2000 | 16 | density = 2000 | ||
17 | 17 | ||||
18 | 18 | ||||
19 | class Stone(Material): | 19 | class Stone(Material): | ||
20 | density = 1600 | 20 | density = 1600 | ||
21 | 21 | ||||
22 | 22 | ||||
23 | class Wood(Material): | 23 | class Wood(Material): | ||
24 | density = 600 | 24 | density = 600 | ||
25 | 25 | ||||
26 | 26 | ||||
27 | class Steel(Material): | 27 | class Steel(Material): | ||
28 | density = 7700 | 28 | density = 7700 | ||
29 | 29 | ||||
30 | 30 | ||||
31 | class Factory: | 31 | class Factory: | ||
32 | all_factories = [] | 32 | all_factories = [] | ||
33 | 33 | ||||
34 | known_materials = { | 34 | known_materials = { | ||
35 | 'Concrete': Concrete, | 35 | 'Concrete': Concrete, | ||
36 | 'Brick': Brick, | 36 | 'Brick': Brick, | ||
37 | 'Stone': Stone, | 37 | 'Stone': Stone, | ||
38 | 'Wood': Wood, | 38 | 'Wood': Wood, | ||
39 | 'Steel': Steel | 39 | 'Steel': Steel | ||
40 | } | 40 | } | ||
41 | 41 | ||||
42 | def __init__(self): | 42 | def __init__(self): | ||
43 | self.created = [] | 43 | self.created = [] | ||
44 | Factory.all_factories.append(self) | 44 | Factory.all_factories.append(self) | ||
45 | 45 | ||||
46 | def __call__(self, *args, **kargs): | 46 | def __call__(self, *args, **kargs): | ||
n | n | 47 | """This method is not long, it's monumental.""" | ||
47 | if args and kargs or not args and not kargs: | 48 | if args and kargs or not args and not kargs: | ||
48 | raise ValueError | 49 | raise ValueError | ||
49 | 50 | ||||
50 | if kargs: | 51 | if kargs: | ||
51 | result = [] | 52 | result = [] | ||
52 | for material_name, mass in kargs.items(): | 53 | for material_name, mass in kargs.items(): | ||
53 | if material_name not in Factory.known_materials: | 54 | if material_name not in Factory.known_materials: | ||
54 | raise ValueError(f"Unknown material: {material_name}") | 55 | raise ValueError(f"Unknown material: {material_name}") | ||
55 | 56 | ||||
56 | material = Factory.known_materials[material_name] | 57 | material = Factory.known_materials[material_name] | ||
57 | self.created.append(Factory.known_materials[material_name](mass)) | 58 | self.created.append(Factory.known_materials[material_name](mass)) | ||
58 | result.append(material(mass)) | 59 | result.append(material(mass)) | ||
59 | 60 | ||||
60 | return tuple(result) | 61 | return tuple(result) | ||
61 | 62 | ||||
62 | if args: | 63 | if args: | ||
63 | for material in args: | 64 | for material in args: | ||
64 | if material.__class__.__name__ not in Factory.known_materials: | 65 | if material.__class__.__name__ not in Factory.known_materials: | ||
65 | raise ValueError(f"Unknown material: {material_name}") | 66 | raise ValueError(f"Unknown material: {material_name}") | ||
66 | 67 | ||||
67 | for material in args: | 68 | for material in args: | ||
68 | if material.used: | 69 | if material.used: | ||
69 | raise AssertionError | 70 | raise AssertionError | ||
70 | 71 | ||||
71 | for material in args: | 72 | for material in args: | ||
72 | material.used = True | 73 | material.used = True | ||
73 | 74 | ||||
74 | for material in self.created: | 75 | for material in self.created: | ||
75 | for names in args: | 76 | for names in args: | ||
76 | if material.__class__.__name__ is names.__class__.__name__: | 77 | if material.__class__.__name__ is names.__class__.__name__: | ||
77 | material.used = True | 78 | material.used = True | ||
78 | 79 | ||||
79 | material_name = [] | 80 | material_name = [] | ||
80 | 81 | ||||
81 | for material in args: | 82 | for material in args: | ||
82 | material_name.append(material.__class__.__name__) | 83 | material_name.append(material.__class__.__name__) | ||
83 | 84 | ||||
84 | new_material_name = '_'.join(material_name) | 85 | new_material_name = '_'.join(material_name) | ||
85 | 86 | ||||
86 | material_mass = sum(material.mass for material in args) | 87 | material_mass = sum(material.mass for material in args) | ||
87 | 88 | ||||
88 | if new_material_name in Factory.known_materials: | 89 | if new_material_name in Factory.known_materials: | ||
89 | self.created.append(Factory.known_materials[new_material_name](material_mass)) | 90 | self.created.append(Factory.known_materials[new_material_name](material_mass)) | ||
90 | return Factory.known_materials[new_material_name](material_mass) | 91 | return Factory.known_materials[new_material_name](material_mass) | ||
91 | 92 | ||||
92 | original_materials_names = new_material_name.split('_') | 93 | original_materials_names = new_material_name.split('_') | ||
93 | 94 | ||||
94 | material_density = 0 | 95 | material_density = 0 | ||
95 | for material in original_materials_names: | 96 | for material in original_materials_names: | ||
96 | material_density += Factory.known_materials[material].density | 97 | material_density += Factory.known_materials[material].density | ||
97 | 98 | ||||
98 | material_density /= len(original_materials_names) | 99 | material_density /= len(original_materials_names) | ||
99 | 100 | ||||
100 | new_material = type(new_material_name, (Material,), { | 101 | new_material = type(new_material_name, (Material,), { | ||
101 | 'density': material_density, | 102 | 'density': material_density, | ||
t | 102 | '__init__': lambda self, mass: Material.__init__(self, mass), | t | ||
103 | 'volume': property(lambda self: self.mass / self.density), | ||||
104 | 'used': False, | ||||
105 | }) | 103 | }) | ||
106 | 104 | ||||
107 | Factory.known_materials[new_material_name] = new_material | 105 | Factory.known_materials[new_material_name] = new_material | ||
108 | self.created.append(Factory.known_materials[new_material_name](material_mass)) | 106 | self.created.append(Factory.known_materials[new_material_name](material_mass)) | ||
109 | 107 | ||||
110 | return new_material(material_mass) | 108 | return new_material(material_mass) | ||
111 | 109 | ||||
112 | def get_total_volume(self): | 110 | def get_total_volume(self): | ||
113 | total_volume = 0 | 111 | total_volume = 0 | ||
114 | for materials in self.created: | 112 | for materials in self.created: | ||
115 | if materials.used is False: | 113 | if materials.used is False: | ||
116 | total_volume += materials.volume | 114 | total_volume += materials.volume | ||
117 | return total_volume | 115 | return total_volume | ||
118 | 116 | ||||
119 | def can_build(self, volume_needed): | 117 | def can_build(self, volume_needed): | ||
120 | return self.get_total_volume() >= volume_needed | 118 | return self.get_total_volume() >= volume_needed | ||
121 | 119 | ||||
122 | @classmethod | 120 | @classmethod | ||
123 | def can_build_together(cls, volume_needed): | 121 | def can_build_together(cls, volume_needed): | ||
124 | total_volume = 0 | 122 | total_volume = 0 | ||
125 | 123 | ||||
126 | for cur in range(0, len(cls.all_factories)): | 124 | for cur in range(0, len(cls.all_factories)): | ||
127 | total_volume += cls.all_factories[cur].get_total_volume() | 125 | total_volume += cls.all_factories[cur].get_total_volume() | ||
128 | return total_volume >= volume_needed | 126 | return total_volume >= volume_needed |
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 | ||
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 | ||||
n | n | 10 | |||
10 | class Concrete(Material): | 11 | class Concrete(Material): | ||
n | 11 | density = 2500 | n | 12 | density = 2500 |
13 | |||||
12 | 14 | ||||
13 | class Brick(Material): | 15 | class Brick(Material): | ||
n | 14 | density = 2000 | n | 16 | density = 2000 |
17 | |||||
15 | 18 | ||||
16 | class Stone(Material): | 19 | class Stone(Material): | ||
n | 17 | density = 1600 | n | 20 | density = 1600 |
21 | |||||
18 | 22 | ||||
19 | class Wood(Material): | 23 | class Wood(Material): | ||
20 | density = 600 | 24 | density = 600 | ||
21 | 25 | ||||
n | n | 26 | |||
22 | class Steel(Material): | 27 | class Steel(Material): | ||
23 | density = 7700 | 28 | density = 7700 | ||
n | n | 29 | |||
24 | 30 | ||||
25 | class Factory: | 31 | class Factory: | ||
26 | all_factories = [] | 32 | all_factories = [] | ||
27 | 33 | ||||
28 | known_materials = { | 34 | known_materials = { | ||
29 | 'Concrete': Concrete, | 35 | 'Concrete': Concrete, | ||
30 | 'Brick': Brick, | 36 | 'Brick': Brick, | ||
31 | 'Stone': Stone, | 37 | 'Stone': Stone, | ||
32 | 'Wood': Wood, | 38 | 'Wood': Wood, | ||
33 | 'Steel': Steel | 39 | 'Steel': Steel | ||
34 | } | 40 | } | ||
35 | 41 | ||||
36 | def __init__(self): | 42 | def __init__(self): | ||
37 | self.created = [] | 43 | self.created = [] | ||
38 | Factory.all_factories.append(self) | 44 | Factory.all_factories.append(self) | ||
39 | 45 | ||||
40 | def __call__(self, *args, **kargs): | 46 | def __call__(self, *args, **kargs): | ||
41 | if args and kargs or not args and not kargs: | 47 | if args and kargs or not args and not kargs: | ||
42 | raise ValueError | 48 | raise ValueError | ||
43 | 49 | ||||
44 | if kargs: | 50 | if kargs: | ||
45 | result = [] | 51 | result = [] | ||
46 | for material_name, mass in kargs.items(): | 52 | for material_name, mass in kargs.items(): | ||
47 | if material_name not in Factory.known_materials: | 53 | if material_name not in Factory.known_materials: | ||
48 | raise ValueError(f"Unknown material: {material_name}") | 54 | raise ValueError(f"Unknown material: {material_name}") | ||
49 | 55 | ||||
50 | material = Factory.known_materials[material_name] | 56 | material = Factory.known_materials[material_name] | ||
51 | self.created.append(Factory.known_materials[material_name](mass)) | 57 | self.created.append(Factory.known_materials[material_name](mass)) | ||
52 | result.append(material(mass)) | 58 | result.append(material(mass)) | ||
n | 53 | n | 59 | ||
54 | return tuple(result) | 60 | return tuple(result) | ||
55 | 61 | ||||
56 | if args: | 62 | if args: | ||
57 | for material in args: | 63 | for material in args: | ||
58 | if material.__class__.__name__ not in Factory.known_materials: | 64 | if material.__class__.__name__ not in Factory.known_materials: | ||
n | 59 | raise ValueError(f"Unknown material") | n | 65 | raise ValueError(f"Unknown material: {material_name}") |
60 | 66 | ||||
61 | for material in args: | 67 | for material in args: | ||
62 | if material.used: | 68 | if material.used: | ||
63 | raise AssertionError | 69 | raise AssertionError | ||
n | 64 | n | 70 | ||
65 | for material in args: | 71 | for material in args: | ||
66 | material.used = True | 72 | material.used = True | ||
n | 67 | n | 73 | ||
68 | for material in self.created: | 74 | for material in self.created: | ||
69 | for names in args: | 75 | for names in args: | ||
70 | if material.__class__.__name__ is names.__class__.__name__: | 76 | if material.__class__.__name__ is names.__class__.__name__: | ||
71 | material.used = True | 77 | material.used = True | ||
72 | 78 | ||||
73 | material_name = [] | 79 | material_name = [] | ||
74 | 80 | ||||
75 | for material in args: | 81 | for material in args: | ||
76 | material_name.append(material.__class__.__name__) | 82 | material_name.append(material.__class__.__name__) | ||
77 | 83 | ||||
78 | new_material_name = '_'.join(material_name) | 84 | new_material_name = '_'.join(material_name) | ||
79 | 85 | ||||
80 | material_mass = sum(material.mass for material in args) | 86 | material_mass = sum(material.mass for material in args) | ||
81 | 87 | ||||
82 | if new_material_name in Factory.known_materials: | 88 | if new_material_name in Factory.known_materials: | ||
83 | self.created.append(Factory.known_materials[new_material_name](material_mass)) | 89 | self.created.append(Factory.known_materials[new_material_name](material_mass)) | ||
84 | return Factory.known_materials[new_material_name](material_mass) | 90 | return Factory.known_materials[new_material_name](material_mass) | ||
85 | 91 | ||||
86 | original_materials_names = new_material_name.split('_') | 92 | original_materials_names = new_material_name.split('_') | ||
87 | 93 | ||||
88 | material_density = 0 | 94 | material_density = 0 | ||
89 | for material in original_materials_names: | 95 | for material in original_materials_names: | ||
90 | material_density += Factory.known_materials[material].density | 96 | material_density += Factory.known_materials[material].density | ||
91 | 97 | ||||
n | 92 | material_density/= len(original_materials_names) | n | 98 | material_density /= len(original_materials_names) |
93 | 99 | ||||
94 | new_material = type(new_material_name, (Material,), { | 100 | new_material = type(new_material_name, (Material,), { | ||
95 | 'density': material_density, | 101 | 'density': material_density, | ||
n | 96 | '__init__': lambda self, mass: Material.__init__(self, mass), | n | 102 | '__init__': lambda self, mass: Material.__init__(self, mass), |
97 | 'volume': property(lambda self: self.mass / self.density), | 103 | 'volume': property(lambda self: self.mass / self.density), | ||
98 | 'used': False, | 104 | 'used': False, | ||
99 | }) | 105 | }) | ||
n | 100 | n | 106 | ||
101 | Factory.known_materials[new_material_name] = new_material | 107 | Factory.known_materials[new_material_name] = new_material | ||
102 | self.created.append(Factory.known_materials[new_material_name](material_mass)) | 108 | self.created.append(Factory.known_materials[new_material_name](material_mass)) | ||
103 | 109 | ||||
104 | return new_material(material_mass) | 110 | return new_material(material_mass) | ||
105 | 111 | ||||
106 | def get_total_volume(self): | 112 | def get_total_volume(self): | ||
107 | total_volume = 0 | 113 | total_volume = 0 | ||
108 | for materials in self.created: | 114 | for materials in self.created: | ||
109 | if materials.used is False: | 115 | if materials.used is False: | ||
110 | total_volume += materials.volume | 116 | total_volume += materials.volume | ||
111 | return total_volume | 117 | return total_volume | ||
n | 112 | n | 118 | ||
113 | def can_build(self, volume_needed): | 119 | def can_build(self, volume_needed): | ||
114 | return self.get_total_volume() >= volume_needed | 120 | return self.get_total_volume() >= volume_needed | ||
115 | 121 | ||||
116 | @classmethod | 122 | @classmethod | ||
117 | def can_build_together(cls, volume_needed): | 123 | def can_build_together(cls, volume_needed): | ||
118 | total_volume = 0 | 124 | total_volume = 0 | ||
119 | 125 | ||||
120 | for cur in range(0, len(cls.all_factories)): | 126 | for cur in range(0, len(cls.all_factories)): | ||
n | 121 | total_volume += cls.all_factories[cur].get_total_volume() | n | 127 | total_volume += cls.all_factories[cur].get_total_volume() |
122 | print(total_volume) | ||||
123 | return total_volume >= volume_needed | 128 | return total_volume >= volume_needed | ||
t | 124 | t | |||
125 | factory1 = Factory() | ||||
126 | brick1, wood1 = factory1(Brick=2000, Wood=1200) | ||||
127 | print(brick1.volume) # 1.0 | ||||
128 | print(wood1.volume) # 2.0 | ||||
129 | brick_wood1 = factory1(brick1, wood1) | ||||
130 | print(brick_wood1.volume) # 2.46... | ||||
131 | print(factory1.can_build(3)) # False | ||||
132 | |||||
133 | factory2 = Factory() | ||||
134 | brick2, wood2 = factory2(Brick=2000, Wood=1200) | ||||
135 | print(brick2.volume) # 1.0 | ||||
136 | print(wood2.volume) # 2.0 | ||||
137 | brick_wood2 = factory2(brick2, wood2) | ||||
138 | print(brick_wood2.volume) # 2.46... | ||||
139 | print(factory2.can_build(3)) # False | ||||
140 | |||||
141 | print(Factory.can_build_together(3)) # True |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|