1class Material:
2 density = 1
3
4 def __init__(self, weight):
5 self.weight = weight
6 self.is_valid = True
7
8 @property
9 def volume(self):
10 return self.weight / self.density
11
12
13class Concrete(Material):
14 density = 2500
15
16
17class Brick(Material):
18 density = 2000
19
20
21class Stone(Material):
22 density = 1600
23
24
25class Wood(Material):
26 density = 600
27
28
29class Steel(Material):
30 density = 7700
31
32existing_materials = {"Concrete": Concrete, "Brick": Brick, "Stone": Stone, "Wood": Wood, "Steel": Steel}
33
34
35class Factory:
36 created_factories = []
37
38 def __init__(self):
39 self.created_materials = []
40 Factory.created_factories.append(self)
41
42 def __call__(self, *args, **kwargs):
43 if not args:
44 if not kwargs:
45 raise ValueError
46 return self.__create_new_materials(kwargs)
47 else:
48 if kwargs:
49 raise ValueError
50 new_name, new_weight, new_density = self.__get_new_name_weight_density(args)
51 return self.__create_and_add_material(new_name, new_weight, new_density)
52
53 def __create_and_add_material(self, name, weight, density):
54 if name in existing_materials:
55 new_material = existing_materials[name](weight)
56 self.created_materials.append(new_material)
57 return new_material
58
59 new_class = type(name, (Material,), {})
60 new_class.density = density
61 existing_materials[name] = new_class
62
63 new_material = existing_materials[name](weight)
64 self.created_materials.append(new_material)
65 return new_material
66
67 def __get_new_name_weight_density(self, args):
68 weight_of_new_material = 0
69 input_materials = []
70 for material in args:
71 if not material.is_valid:
72 raise AssertionError
73 material.is_valid = False
74 input_materials.append(type(material).__name__)
75 weight_of_new_material += material.weight
76
77 basic_materials = set()
78
79 for material in input_materials:
80 basic_materials.update(material.split("_"))
81 name_of_new_material = "_".join(sorted(basic_materials))
82
83 density_of_new_material = sum(existing_materials[str(material)].density for material in basic_materials)
84 density_of_new_material /= len(basic_materials)
85 return name_of_new_material, weight_of_new_material, density_of_new_material
86
87 def __create_new_materials(self, kwargs):
88 result = []
89 for material, weight in kwargs.items():
90 if material not in existing_materials.keys():
91 raise ValueError
92 else:
93 new_material = existing_materials[material](weight)
94 self.created_materials.append(new_material)
95 result.append(new_material)
96 return tuple(result)
97
98 def can_build(self, wall_volume):
99 return wall_volume <= self.__get_factory_volume()
100
101 def __get_factory_volume(self):
102 return sum(material.volume for material in self.created_materials if material.is_valid)
103
104 @classmethod
105 def can_build_together(cls, wall_volume):
106 factory_volume_together = sum(factory.__get_factory_volume() for factory in cls.created_factories)
107 return wall_volume <= factory_volume_together
.....F....
======================================================================
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 50, in __call__
new_name, new_weight, new_density = self.__get_new_name_weight_density(args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 72, in __get_new_name_weight_density
raise AssertionError
AssertionError
----------------------------------------------------------------------
Ran 10 tests in 0.016s
FAILED (failures=1)
n | 1 | n | |||
2 | class Material: | 1 | class Material: | ||
3 | density = 1 | 2 | density = 1 | ||
n | 4 | is_valid = True | n | ||
5 | 3 | ||||
6 | def __init__(self, weight): | 4 | def __init__(self, weight): | ||
7 | self.weight = weight | 5 | self.weight = weight | ||
n | n | 6 | self.is_valid = True | ||
8 | 7 | ||||
9 | @property | 8 | @property | ||
10 | def volume(self): | 9 | def volume(self): | ||
11 | return self.weight / self.density | 10 | return self.weight / self.density | ||
12 | 11 | ||||
13 | 12 | ||||
14 | class Concrete(Material): | 13 | class Concrete(Material): | ||
15 | density = 2500 | 14 | density = 2500 | ||
16 | 15 | ||||
17 | 16 | ||||
18 | class Brick(Material): | 17 | class Brick(Material): | ||
19 | density = 2000 | 18 | density = 2000 | ||
20 | 19 | ||||
21 | 20 | ||||
22 | class Stone(Material): | 21 | class Stone(Material): | ||
23 | density = 1600 | 22 | density = 1600 | ||
24 | 23 | ||||
25 | 24 | ||||
26 | class Wood(Material): | 25 | class Wood(Material): | ||
27 | density = 600 | 26 | density = 600 | ||
28 | 27 | ||||
29 | 28 | ||||
30 | class Steel(Material): | 29 | class Steel(Material): | ||
31 | density = 7700 | 30 | density = 7700 | ||
32 | 31 | ||||
33 | existing_materials = {"Concrete": Concrete, "Brick": Brick, "Stone": Stone, "Wood": Wood, "Steel": Steel} | 32 | existing_materials = {"Concrete": Concrete, "Brick": Brick, "Stone": Stone, "Wood": Wood, "Steel": Steel} | ||
34 | 33 | ||||
n | n | 34 | |||
35 | class Factory: | 35 | class Factory: | ||
36 | created_factories = [] | 36 | created_factories = [] | ||
37 | 37 | ||||
38 | def __init__(self): | 38 | def __init__(self): | ||
39 | self.created_materials = [] | 39 | self.created_materials = [] | ||
40 | Factory.created_factories.append(self) | 40 | Factory.created_factories.append(self) | ||
41 | 41 | ||||
42 | def __call__(self, *args, **kwargs): | 42 | def __call__(self, *args, **kwargs): | ||
n | 43 | if len(args) == 0: | n | 43 | if not args: |
44 | if len(kwargs) == 0: | 44 | if not kwargs: | ||
45 | raise ValueError | 45 | raise ValueError | ||
n | n | 46 | return self.__create_new_materials(kwargs) | ||
47 | else: | ||||
48 | if kwargs: | ||||
49 | raise ValueError | ||||
50 | new_name, new_weight, new_density = self.__get_new_name_weight_density(args) | ||||
51 | return self.__create_and_add_material(new_name, new_weight, new_density) | ||||
46 | 52 | ||||
n | 47 | result = [] | n | 53 | def __create_and_add_material(self, name, weight, density): |
48 | for material, weight in kwargs.items(): | 54 | if name in existing_materials: | ||
49 | if material not in existing_materials.keys(): | ||||
50 | raise ValueError | ||||
51 | else: | ||||
52 | new_material = existing_materials[material](weight) | 55 | new_material = existing_materials[name](weight) | ||
53 | self.created_materials.append(new_material) | ||||
54 | result.append(new_material) | ||||
55 | return tuple(result) | ||||
56 | else: | ||||
57 | if len(kwargs) != 0: | ||||
58 | raise ValueError | ||||
59 | |||||
60 | weight_of_new_material = 0 | ||||
61 | input_materials = [] | ||||
62 | for material in args: | ||||
63 | if not material.is_valid: | ||||
64 | raise AssertionError | ||||
65 | material.is_valid = False | ||||
66 | input_materials.append(str(type(material).__name__)) | ||||
67 | weight_of_new_material += material.weight | ||||
68 | |||||
69 | basic_materials = set() | ||||
70 | for material in input_materials: | ||||
71 | basic_materials.update(material.split("_")) | ||||
72 | name_of_new_material = "_".join(sorted(basic_materials)) | ||||
73 | |||||
74 | density_of_new_material = sum(existing_materials[str(material)].density for material in basic_materials) | ||||
75 | density_of_new_material /= len(basic_materials) | ||||
76 | |||||
77 | if name_of_new_material in existing_materials.keys(): | ||||
78 | new_material = existing_materials[name_of_new_material](weight_of_new_material) | ||||
79 | self.created_materials.append(new_material) | ||||
80 | return new_material | ||||
81 | |||||
82 | new_class = type(name_of_new_material, (Material,), {}) | ||||
83 | new_class.density = density_of_new_material | ||||
84 | existing_materials[name_of_new_material] = new_class | ||||
85 | |||||
86 | new_material = new_class(weight_of_new_material) | ||||
87 | self.created_materials.append(new_material) | 56 | self.created_materials.append(new_material) | ||
88 | return new_material | 57 | return new_material | ||
n | n | 58 | |||
59 | new_class = type(name, (Material,), {}) | ||||
60 | new_class.density = density | ||||
61 | existing_materials[name] = new_class | ||||
62 | |||||
63 | new_material = existing_materials[name](weight) | ||||
64 | self.created_materials.append(new_material) | ||||
65 | return new_material | ||||
66 | |||||
67 | def __get_new_name_weight_density(self, args): | ||||
68 | weight_of_new_material = 0 | ||||
69 | input_materials = [] | ||||
70 | for material in args: | ||||
71 | if not material.is_valid: | ||||
72 | raise AssertionError | ||||
73 | material.is_valid = False | ||||
74 | input_materials.append(type(material).__name__) | ||||
75 | weight_of_new_material += material.weight | ||||
76 | |||||
77 | basic_materials = set() | ||||
78 | |||||
79 | for material in input_materials: | ||||
80 | basic_materials.update(material.split("_")) | ||||
81 | name_of_new_material = "_".join(sorted(basic_materials)) | ||||
82 | |||||
83 | density_of_new_material = sum(existing_materials[str(material)].density for material in basic_materials) | ||||
84 | density_of_new_material /= len(basic_materials) | ||||
85 | return name_of_new_material, weight_of_new_material, density_of_new_material | ||||
86 | |||||
87 | def __create_new_materials(self, kwargs): | ||||
88 | result = [] | ||||
89 | for material, weight in kwargs.items(): | ||||
90 | if material not in existing_materials.keys(): | ||||
91 | raise ValueError | ||||
92 | else: | ||||
93 | new_material = existing_materials[material](weight) | ||||
94 | self.created_materials.append(new_material) | ||||
95 | result.append(new_material) | ||||
96 | return tuple(result) | ||||
89 | 97 | ||||
90 | def can_build(self, wall_volume): | 98 | def can_build(self, wall_volume): | ||
91 | return wall_volume <= self.__get_factory_volume() | 99 | return wall_volume <= self.__get_factory_volume() | ||
92 | 100 | ||||
93 | def __get_factory_volume(self): | 101 | def __get_factory_volume(self): | ||
94 | return sum(material.volume for material in self.created_materials if material.is_valid) | 102 | return sum(material.volume for material in self.created_materials if material.is_valid) | ||
95 | 103 | ||||
96 | @classmethod | 104 | @classmethod | ||
97 | def can_build_together(cls, wall_volume): | 105 | def can_build_together(cls, wall_volume): | ||
t | 98 | factory_volume_together = 0 | t | 106 | factory_volume_together = sum(factory.__get_factory_volume() for factory in cls.created_factories) |
99 | for factory in cls.created_factories: | ||||
100 | factory_volume_together += factory.__get_factory_volume() | ||||
101 | return wall_volume <= factory_volume_together | 107 | return wall_volume <= factory_volume_together |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|