1class Material:
2 def __init__(self, mass:int):
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 def __init__(self):
32 self.materials = {
33 "Concrete": Concrete,
34 "Brick": Brick,
35 "Stone": Stone,
36 "Wood": Wood,
37 "Steel": Steel
38 }
39
40 def __call__(self, *args, **kwargs):
41 if args and kwargs:
42 raise ValueError("Can't call both *args and **kwargs")
43
44 if kwargs:
45 return self._materials_from_named_argument(**kwargs)
46 elif args:
47 return self._materials_from_pos_argument(*args)
48
49 def _materials_from_named_argument(self, **kwargs):
50 materials = []
51 for material, mass in kwargs.items():
52 if material not in self.materials:
53 raise ValueError("Invalid material")
54 curr_class = self.materials[material]
55 materials.append(curr_class(mass))
56 return tuple(materials)
57
58 def _materials_from_pos_argument(self, *args):
59 used_materials = []
60 final_mass = 0
61
62 for material in args:
63 material_name = material.__class__.__name__
64 if material_name not in self.materials:
65 raise ValueError("Invalid material")
66 used_materials.append(material)
67 final_mass += material.mass
68
69 class_name = "_".join(sorted(material.__class__.__name__ for material in used_materials))
70 if class_name in self.materials:
71 return self.materials[class_name]
72
73 avg_density = sum(material.density for material in used_materials) / len(used_materials)
74
75 # Volume от Material не работи.....
76 new_material = type(class_name, (Material,), {"density": avg_density})
77 self.materials[class_name] = new_material
78 return new_material(final_mass)
79
80 def can_build(self, wall_volume:int):
81 sum_volume = 0
82 for material in self.materials.values():
83 volume = material.volume
84
85 return sum_volume >= wall_volume
FFE..FFFF.
======================================================================
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 45, in __call__
return self._materials_from_named_argument(**kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 53, in _materials_from_named_argument
raise ValueError("Invalid material")
ValueError: Invalid material
======================================================================
FAIL: test_bad_input (test.TestFactory.test_bad_input)
Test calling a factory using bad input.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 46, in test_bad_input
with self.assertRaises(ValueError):
AssertionError: ValueError not raised
======================================================================
FAIL: test_can_build (test.TestFactory.test_can_build)
Test can_build methods.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 174, in test_can_build
self.assertTrue(self.factory1.can_build(2.0))
AssertionError: False is not true
======================================================================
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 101, in test_positional_arguments_multiple_argument_from_initial_set
with self.assertRaises(AssertionError):
AssertionError: AssertionError not raised
======================================================================
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: 'Brick_Concrete_Stone_Steel_Wood' != 'Brick_Concrete_Steel_Stone_Wood'
- Brick_Concrete_Stone_Steel_Wood
? ------
+ Brick_Concrete_Steel_Stone_Wood
? ++++++
======================================================================
FAIL: test_positional_arguments_single_argument (test.TestFactory.test_positional_arguments_single_argument)
Test calling a factory using a sigle positional argument.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 80, in test_positional_arguments_single_argument
self.assertIs(type(concrete2), solution.Concrete)
AssertionError: <class 'type'> is not <class 'solution.Concrete'>
======================================================================
FAIL: test_positional_arguments_singletons (test.TestFactory.test_positional_arguments_singletons)
Test dynamically created classes uniqueness.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 138, in test_positional_arguments_singletons
self.assertIs(type(brick_concrete_wood1), type(brick_concrete_wood2))
AssertionError: <class 'solution.Brick_Concrete_Wood'> is not <class 'type'>
----------------------------------------------------------------------
Ran 10 tests in 0.009s
FAILED (failures=6, errors=1)
f | 1 | class Material: | f | 1 | class Material: |
2 | def __init__(self, mass:int): | 2 | def __init__(self, mass:int): | ||
3 | self.mass = mass | 3 | self.mass = mass | ||
4 | 4 | ||||
5 | @property | 5 | @property | ||
6 | def volume(self): | 6 | def volume(self): | ||
7 | return self.mass/self.density | 7 | return self.mass/self.density | ||
8 | 8 | ||||
9 | 9 | ||||
10 | class Concrete(Material): | 10 | class Concrete(Material): | ||
11 | density = 2500 | 11 | density = 2500 | ||
12 | 12 | ||||
13 | 13 | ||||
14 | class Brick(Material): | 14 | class Brick(Material): | ||
15 | density = 2000 | 15 | density = 2000 | ||
16 | 16 | ||||
17 | 17 | ||||
18 | class Stone(Material): | 18 | class Stone(Material): | ||
19 | density = 1600 | 19 | density = 1600 | ||
20 | 20 | ||||
21 | 21 | ||||
22 | class Wood(Material): | 22 | class Wood(Material): | ||
23 | density = 600 | 23 | density = 600 | ||
24 | 24 | ||||
25 | 25 | ||||
26 | class Steel(Material): | 26 | class Steel(Material): | ||
27 | density = 7700 | 27 | density = 7700 | ||
28 | 28 | ||||
29 | 29 | ||||
30 | class Factory: | 30 | class Factory: | ||
31 | def __init__(self): | 31 | def __init__(self): | ||
32 | self.materials = { | 32 | self.materials = { | ||
n | 33 | "Concrete":Concrete, | n | 33 | "Concrete": Concrete, |
34 | "Brick":Brick, | 34 | "Brick": Brick, | ||
35 | "Stone":Stone, | 35 | "Stone": Stone, | ||
36 | "Wood":Wood, | 36 | "Wood": Wood, | ||
37 | "Steel":Steel | 37 | "Steel": Steel | ||
38 | } | 38 | } | ||
39 | 39 | ||||
40 | def __call__(self, *args, **kwargs): | 40 | def __call__(self, *args, **kwargs): | ||
41 | if args and kwargs: | 41 | if args and kwargs: | ||
42 | raise ValueError("Can't call both *args and **kwargs") | 42 | raise ValueError("Can't call both *args and **kwargs") | ||
43 | 43 | ||||
44 | if kwargs: | 44 | if kwargs: | ||
n | 45 | materials = [] | n | 45 | return self._materials_from_named_argument(**kwargs) |
46 | for material, mass in kwargs.items(): | ||||
47 | if material not in self.materials: | ||||
48 | raise ValueError("Invalid material") | ||||
49 | curr_class = self.materials[material] | ||||
50 | materials.append(curr_class(mass)) | ||||
51 | return tuple(materials) | ||||
52 | elif args: | 46 | elif args: | ||
n | n | 47 | return self._materials_from_pos_argument(*args) | ||
48 | |||||
49 | def _materials_from_named_argument(self, **kwargs): | ||||
53 | used_materials = [] | 50 | materials = [] | ||
54 | final_mass = 0 | 51 | for material, mass in kwargs.items(): | ||
52 | if material not in self.materials: | ||||
53 | raise ValueError("Invalid material") | ||||
54 | curr_class = self.materials[material] | ||||
55 | materials.append(curr_class(mass)) | ||||
56 | return tuple(materials) | ||||
55 | 57 | ||||
n | 56 | for material in args: | n | 58 | def _materials_from_pos_argument(self, *args): |
57 | material_name = material.__class__.__name__ | 59 | used_materials = [] | ||
58 | if material_name not in self.materials: | 60 | final_mass = 0 | ||
59 | raise ValueError("Invalid material") | ||||
60 | used_materials.append(material) | ||||
61 | final_mass += material.mass | ||||
62 | 61 | ||||
n | n | 62 | for material in args: | ||
63 | material_name = material.__class__.__name__ | ||||
64 | if material_name not in self.materials: | ||||
65 | raise ValueError("Invalid material") | ||||
66 | used_materials.append(material) | ||||
67 | final_mass += material.mass | ||||
68 | |||||
63 | class_name = "_".join(sorted(material.__class__.__name__ for material in used_materials)) | 69 | class_name = "_".join(sorted(material.__class__.__name__ for material in used_materials)) | ||
64 | if class_name in self.materials: | 70 | if class_name in self.materials: | ||
65 | return self.materials[class_name] | 71 | return self.materials[class_name] | ||
66 | 72 | ||||
n | 67 | avg_density = sum(material.density for material in used_materials) / len(used_materials) | n | 73 | avg_density = sum(material.density for material in used_materials) / len(used_materials) |
68 | 74 | ||||
n | 69 | # Volume от Material не работи..... | n | 75 | # Volume от Material не работи..... |
70 | new_material = type(class_name, (Material,), {"density": avg_density, "volume": property(final_mass/avg_density)}) | 76 | new_material = type(class_name, (Material,), {"density": avg_density}) | ||
71 | self.materials[class_name] = new_material | 77 | self.materials[class_name] = new_material | ||
72 | return new_material(final_mass) | 78 | return new_material(final_mass) | ||
73 | 79 | ||||
74 | def can_build(self, wall_volume:int): | 80 | def can_build(self, wall_volume:int): | ||
75 | sum_volume = 0 | 81 | sum_volume = 0 | ||
76 | for material in self.materials.values(): | 82 | for material in self.materials.values(): | ||
77 | volume = material.volume | 83 | volume = material.volume | ||
n | 78 | print(volume) | n | ||
79 | 84 | ||||
t | 80 | if sum_volume >= wall_volume: | t | 85 | return sum_volume >= wall_volume |
81 | return True | ||||
82 | |||||
83 | return False |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|