Домашни > Another brick in the wall > Решения > Решението на Илиан Запрянов

Резултати
9 точки от тестове
0 точки от учител

9 точки общо

9 успешни теста
1 неуспешни теста
Код

  1_MATERIALS_DENSITIES = {
  2    'Concrete': 2500,
  3    'Brick': 2000,
  4    'Stone': 1600,
  5    'Wood': 600,
  6    'Steel': 7700,
  7}
  8
  9class Material:
 10    """Base class for materials with mass and density."""
 11
 12    _DENSITY = 1
 13
 14    def __init__(self, mass):
 15        """Initialize the material with a given mass."""
 16        self.mass = mass
 17        self._is_valid = True
 18
 19    @property
 20    def volume(self):
 21        """Calculate the volume of the material."""
 22        return self.mass / self._DENSITY
 23
 24    def validate(self):
 25        """Check if the material is still valid for use."""
 26        if not self._is_valid:
 27            raise AssertionError('Not valid material found.')
 28        
 29    def invalidate(self):
 30        """Mark the material as invalid."""
 31        self._is_valid = False
 32        
 33    def get_base_materials(self):
 34        return [type(self).__name__]
 35
 36
 37class Concrete(Material):
 38    """Concrete material with predefined density."""
 39    _DENSITY = _MATERIALS_DENSITIES['Concrete']
 40
 41
 42class Brick(Material):
 43    """Brick material with predefined density."""
 44    _DENSITY = _MATERIALS_DENSITIES['Brick']
 45
 46
 47class Stone(Material):
 48    """Stone material with predefined density."""
 49    _DENSITY = _MATERIALS_DENSITIES['Stone']
 50
 51
 52class Wood(Material):
 53    """Wood material with predefined density."""
 54    _DENSITY = _MATERIALS_DENSITIES['Wood']
 55
 56
 57class Steel(Material):
 58    """Steel material with predefined density."""
 59    _DENSITY = _MATERIALS_DENSITIES['Steel']
 60
 61
 62class Factory:
 63    """Create and manage materials and alloys."""
 64
 65    _MATERIALS_CREATED = {
 66        'Concrete': Concrete,
 67        'Brick': Brick,
 68        'Stone': Stone,
 69        'Wood': Wood,
 70        'Steel': Steel,
 71    }
 72
 73    all_created_materials = []
 74
 75    def __init__(self):
 76        self.materials_created_by_instance = []
 77
 78    def __call__(self, *args, **kwargs):
 79        """Enable the factory instance to be called."""
 80        if args and kwargs:
 81            raise ValueError('One type of arguments are allowed.')
 82        elif (len(args), len(kwargs)) == (0, 0):
 83            raise ValueError('No arguments found.')
 84
 85        if len(args) > 0:
 86            return self.positional_call(*args)
 87        return self.keyword_call(**kwargs)
 88
 89    def positional_call(self, *args):
 90        """Handle creation of alloys from positional arguments."""
 91
 92        for material in args:
 93            material.validate()
 94            material.invalidate()
 95
 96        base_materials = []
 97        for material in args:
 98                base_materials.extend(material.get_base_materials())
 99
100        unique_base_materials = sorted(set(base_materials))
101
102        alloy_name = '_'.join(unique_base_materials)
103        alloy_density = sum(_MATERIALS_DENSITIES[material] for material in unique_base_materials) / len(unique_base_materials)
104        alloy_mass = sum(material.mass for material in args)
105
106        if alloy_name in self._MATERIALS_CREATED:
107            alloy_class = self._MATERIALS_CREATED[alloy_name]
108        else:
109            alloy_class = self.create_alloy_class(alloy_name, alloy_density, unique_base_materials)
110            
111        alloy_instance = alloy_class(alloy_mass)
112        self.materials_created_by_instance.append(alloy_instance)
113        Factory.all_created_materials.append(alloy_instance)
114
115        return alloy_instance
116
117    def create_alloy_class(self, alloy_name, alloy_density, base_materials):
118        """Dynamically create a class for an alloy."""
119        
120        alloy_class = type(
121            alloy_name,
122            (Material,),
123            {
124                '_DENSITY': alloy_density,
125                '_base_materials': base_materials,
126                'get_base_materials': lambda self: base_materials,
127            }
128        )
129
130        self._MATERIALS_CREATED[alloy_name] = alloy_class
131        _MATERIALS_DENSITIES[alloy_name] = alloy_density
132        return alloy_class
133
134    def keyword_call(self, **kwargs):
135        """Handle creation of materials from keyword arguments."""
136        material_instances = []
137        for material, mass in kwargs.items():
138            if material not in self._MATERIALS_CREATED:
139                raise ValueError('Not valid material found.')
140
141            material_instance = self._MATERIALS_CREATED[material](mass)
142            material_instances.append(material_instance)
143            self.materials_created_by_instance.append(material_instance) 
144            self.all_created_materials.append(material_instance)
145
146        return tuple(material_instances)
147
148    def can_build(self, target):
149        """Check if the factory's materials can build a wall of target volume."""
150        valid_materials = [
151            material for material in self.materials_created_by_instance if material._is_valid
152        ]
153        
154        volume_sum = sum(material.volume for material in valid_materials)
155        return volume_sum >= target
156
157    @classmethod
158    def can_build_together(cls, target):
159        """Check if all factories together can build a wall of target volume."""
160        valid_materials = [
161            material for material in cls.all_created_materials if material._is_valid
162        ]
163        
164        used_materials = set(
165            material for material in cls.all_created_materials if not material._is_valid
166        )
167       
168        final_valid_materials = [material for material in valid_materials if material not in used_materials]
169        total_volume = sum(material.volume for material in final_valid_materials)
170        return total_volume >= target

.....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 86, in __call__
return self.positional_call(*args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 93, in positional_call
material.validate()
File "/tmp/solution.py", line 27, in validate
raise AssertionError('Not valid material found.')
AssertionError: Not valid material found.

----------------------------------------------------------------------
Ran 10 tests in 0.024s

FAILED (failures=1)

Дискусия
История

f1_MATERIALS_DENSITIES = {f1_MATERIALS_DENSITIES = {
2    'Concrete': 2500,2    'Concrete': 2500,
3    'Brick': 2000,3    'Brick': 2000,
4    'Stone': 1600,4    'Stone': 1600,
5    'Wood': 600,5    'Wood': 600,
6    'Steel': 7700,6    'Steel': 7700,
7}7}
88
9class Material:9class Material:
10    """Base class for materials with mass and density."""10    """Base class for materials with mass and density."""
1111
12    _DENSITY = 112    _DENSITY = 1
1313
14    def __init__(self, mass):14    def __init__(self, mass):
15        """Initialize the material with a given mass."""15        """Initialize the material with a given mass."""
16        self.mass = mass16        self.mass = mass
17        self._is_valid = True17        self._is_valid = True
1818
19    @property19    @property
20    def volume(self):20    def volume(self):
21        """Calculate the volume of the material."""21        """Calculate the volume of the material."""
22        return self.mass / self._DENSITY22        return self.mass / self._DENSITY
2323
24    def validate(self):24    def validate(self):
25        """Check if the material is still valid for use."""25        """Check if the material is still valid for use."""
26        if not self._is_valid:26        if not self._is_valid:
27            raise AssertionError('Not valid material found.')27            raise AssertionError('Not valid material found.')
nn28        
29    def invalidate(self):
30        """Mark the material as invalid."""
31        self._is_valid = False
32        
33    def get_base_materials(self):
34        return [type(self).__name__]
2835
2936
30class Concrete(Material):37class Concrete(Material):
31    """Concrete material with predefined density."""38    """Concrete material with predefined density."""
32    _DENSITY = _MATERIALS_DENSITIES['Concrete']39    _DENSITY = _MATERIALS_DENSITIES['Concrete']
3340
3441
35class Brick(Material):42class Brick(Material):
36    """Brick material with predefined density."""43    """Brick material with predefined density."""
37    _DENSITY = _MATERIALS_DENSITIES['Brick']44    _DENSITY = _MATERIALS_DENSITIES['Brick']
3845
3946
40class Stone(Material):47class Stone(Material):
41    """Stone material with predefined density."""48    """Stone material with predefined density."""
42    _DENSITY = _MATERIALS_DENSITIES['Stone']49    _DENSITY = _MATERIALS_DENSITIES['Stone']
4350
4451
45class Wood(Material):52class Wood(Material):
46    """Wood material with predefined density."""53    """Wood material with predefined density."""
47    _DENSITY = _MATERIALS_DENSITIES['Wood']54    _DENSITY = _MATERIALS_DENSITIES['Wood']
4855
4956
50class Steel(Material):57class Steel(Material):
51    """Steel material with predefined density."""58    """Steel material with predefined density."""
52    _DENSITY = _MATERIALS_DENSITIES['Steel']59    _DENSITY = _MATERIALS_DENSITIES['Steel']
5360
5461
55class Factory:62class Factory:
56    """Create and manage materials and alloys."""63    """Create and manage materials and alloys."""
5764
58    _MATERIALS_CREATED = {65    _MATERIALS_CREATED = {
59        'Concrete': Concrete,66        'Concrete': Concrete,
60        'Brick': Brick,67        'Brick': Brick,
61        'Stone': Stone,68        'Stone': Stone,
62        'Wood': Wood,69        'Wood': Wood,
63        'Steel': Steel,70        'Steel': Steel,
64    }71    }
6572
66    all_created_materials = []73    all_created_materials = []
6774
68    def __init__(self):75    def __init__(self):
69        self.materials_created_by_instance = []76        self.materials_created_by_instance = []
7077
71    def __call__(self, *args, **kwargs):78    def __call__(self, *args, **kwargs):
72        """Enable the factory instance to be called."""79        """Enable the factory instance to be called."""
n73        if len(args) > 0 and len(kwargs) > 0:n80        if args and kwargs:
74            raise ValueError('One type of arguments are allowed.')81            raise ValueError('One type of arguments are allowed.')
75        elif (len(args), len(kwargs)) == (0, 0):82        elif (len(args), len(kwargs)) == (0, 0):
76            raise ValueError('No arguments found.')83            raise ValueError('No arguments found.')
7784
78        if len(args) > 0:85        if len(args) > 0:
79            return self.positional_call(*args)86            return self.positional_call(*args)
80        return self.keyword_call(**kwargs)87        return self.keyword_call(**kwargs)
8188
82    def positional_call(self, *args):89    def positional_call(self, *args):
83        """Handle creation of alloys from positional arguments."""90        """Handle creation of alloys from positional arguments."""
n84        args = [arg[0] if isinstance(arg, tuple) else arg for arg in args]n91 
85        for material in args:92        for material in args:
86            material.validate()93            material.validate()
n87            material._is_valid = Falsen94            material.invalidate()
8895
89        base_materials = []96        base_materials = []
90        for material in args:97        for material in args:
n91            if hasattr(material, '_base_materials'):n
92                base_materials.extend(material._base_materials)98                base_materials.extend(material.get_base_materials())
93            else:
94                base_materials.append(type(material).__name__)
9599
96        unique_base_materials = sorted(set(base_materials))100        unique_base_materials = sorted(set(base_materials))
97101
98        alloy_name = '_'.join(unique_base_materials)102        alloy_name = '_'.join(unique_base_materials)
99        alloy_density = sum(_MATERIALS_DENSITIES[material] for material in unique_base_materials) / len(unique_base_materials)103        alloy_density = sum(_MATERIALS_DENSITIES[material] for material in unique_base_materials) / len(unique_base_materials)
100        alloy_mass = sum(material.mass for material in args)104        alloy_mass = sum(material.mass for material in args)
101105
102        if alloy_name in self._MATERIALS_CREATED:106        if alloy_name in self._MATERIALS_CREATED:
103            alloy_class = self._MATERIALS_CREATED[alloy_name]107            alloy_class = self._MATERIALS_CREATED[alloy_name]
104        else:108        else:
105            alloy_class = self.create_alloy_class(alloy_name, alloy_density, unique_base_materials)109            alloy_class = self.create_alloy_class(alloy_name, alloy_density, unique_base_materials)
106            110            
107        alloy_instance = alloy_class(alloy_mass)111        alloy_instance = alloy_class(alloy_mass)
108        self.materials_created_by_instance.append(alloy_instance)112        self.materials_created_by_instance.append(alloy_instance)
109        Factory.all_created_materials.append(alloy_instance)113        Factory.all_created_materials.append(alloy_instance)
110114
111        return alloy_instance115        return alloy_instance
112116
113    def create_alloy_class(self, alloy_name, alloy_density, base_materials):117    def create_alloy_class(self, alloy_name, alloy_density, base_materials):
114        """Dynamically create a class for an alloy."""118        """Dynamically create a class for an alloy."""
nn119        
115        alloy_class = type(120        alloy_class = type(
116            alloy_name,121            alloy_name,
117            (Material,),122            (Material,),
118            {123            {
119                '_DENSITY': alloy_density,124                '_DENSITY': alloy_density,
120                '_base_materials': base_materials,125                '_base_materials': base_materials,
nn126                'get_base_materials': lambda self: base_materials,
121            }127            }
122        )128        )
123129
124        self._MATERIALS_CREATED[alloy_name] = alloy_class130        self._MATERIALS_CREATED[alloy_name] = alloy_class
125        _MATERIALS_DENSITIES[alloy_name] = alloy_density131        _MATERIALS_DENSITIES[alloy_name] = alloy_density
126        return alloy_class132        return alloy_class
127133
128    def keyword_call(self, **kwargs):134    def keyword_call(self, **kwargs):
129        """Handle creation of materials from keyword arguments."""135        """Handle creation of materials from keyword arguments."""
130        material_instances = []136        material_instances = []
131        for material, mass in kwargs.items():137        for material, mass in kwargs.items():
132            if material not in self._MATERIALS_CREATED:138            if material not in self._MATERIALS_CREATED:
133                raise ValueError('Not valid material found.')139                raise ValueError('Not valid material found.')
134140
135            material_instance = self._MATERIALS_CREATED[material](mass)141            material_instance = self._MATERIALS_CREATED[material](mass)
136            material_instances.append(material_instance)142            material_instances.append(material_instance)
137            self.materials_created_by_instance.append(material_instance) 143            self.materials_created_by_instance.append(material_instance) 
138            self.all_created_materials.append(material_instance)144            self.all_created_materials.append(material_instance)
139145
140        return tuple(material_instances)146        return tuple(material_instances)
141147
142    def can_build(self, target):148    def can_build(self, target):
143        """Check if the factory's materials can build a wall of target volume."""149        """Check if the factory's materials can build a wall of target volume."""
144        valid_materials = [150        valid_materials = [
145            material for material in self.materials_created_by_instance if material._is_valid151            material for material in self.materials_created_by_instance if material._is_valid
146        ]152        ]
147        153        
148        volume_sum = sum(material.volume for material in valid_materials)154        volume_sum = sum(material.volume for material in valid_materials)
149        return volume_sum >= target155        return volume_sum >= target
150156
151    @classmethod157    @classmethod
152    def can_build_together(cls, target):158    def can_build_together(cls, target):
153        """Check if all factories together can build a wall of target volume."""159        """Check if all factories together can build a wall of target volume."""
154        valid_materials = [160        valid_materials = [
155            material for material in cls.all_created_materials if material._is_valid161            material for material in cls.all_created_materials if material._is_valid
156        ]162        ]
157        163        
n158        alloy_materials = set(n164        used_materials = set(
159            material for material in cls.all_created_materials if not material._is_valid165            material for material in cls.all_created_materials if not material._is_valid
160        )166        )
161       167       
t162        final_valid_materials = [material for material in valid_materials if material not in alloy_materials]t168        final_valid_materials = [material for material in valid_materials if material not in used_materials]
163        total_volume = sum(material.volume for material in final_valid_materials)169        total_volume = sum(material.volume for material in final_valid_materials)
164        return total_volume >= target170        return total_volume >= target
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1_MATERIALS_DENSITIES = {f1_MATERIALS_DENSITIES = {
2    'Concrete': 2500,2    'Concrete': 2500,
3    'Brick': 2000,3    'Brick': 2000,
4    'Stone': 1600,4    'Stone': 1600,
5    'Wood': 600,5    'Wood': 600,
6    'Steel': 7700,6    'Steel': 7700,
7}7}
88
9class Material:9class Material:
10    """Base class for materials with mass and density."""10    """Base class for materials with mass and density."""
1111
12    _DENSITY = 112    _DENSITY = 1
1313
14    def __init__(self, mass):14    def __init__(self, mass):
15        """Initialize the material with a given mass."""15        """Initialize the material with a given mass."""
16        self.mass = mass16        self.mass = mass
17        self._is_valid = True17        self._is_valid = True
1818
19    @property19    @property
20    def volume(self):20    def volume(self):
21        """Calculate the volume of the material."""21        """Calculate the volume of the material."""
22        return self.mass / self._DENSITY22        return self.mass / self._DENSITY
2323
24    def validate(self):24    def validate(self):
25        """Check if the material is still valid for use."""25        """Check if the material is still valid for use."""
26        if not self._is_valid:26        if not self._is_valid:
27            raise AssertionError('Not valid material found.')27            raise AssertionError('Not valid material found.')
2828
2929
30class Concrete(Material):30class Concrete(Material):
31    """Concrete material with predefined density."""31    """Concrete material with predefined density."""
32    _DENSITY = _MATERIALS_DENSITIES['Concrete']32    _DENSITY = _MATERIALS_DENSITIES['Concrete']
3333
3434
35class Brick(Material):35class Brick(Material):
36    """Brick material with predefined density."""36    """Brick material with predefined density."""
37    _DENSITY = _MATERIALS_DENSITIES['Brick']37    _DENSITY = _MATERIALS_DENSITIES['Brick']
3838
3939
40class Stone(Material):40class Stone(Material):
41    """Stone material with predefined density."""41    """Stone material with predefined density."""
42    _DENSITY = _MATERIALS_DENSITIES['Stone']42    _DENSITY = _MATERIALS_DENSITIES['Stone']
4343
4444
45class Wood(Material):45class Wood(Material):
46    """Wood material with predefined density."""46    """Wood material with predefined density."""
47    _DENSITY = _MATERIALS_DENSITIES['Wood']47    _DENSITY = _MATERIALS_DENSITIES['Wood']
4848
4949
50class Steel(Material):50class Steel(Material):
51    """Steel material with predefined density."""51    """Steel material with predefined density."""
52    _DENSITY = _MATERIALS_DENSITIES['Steel']52    _DENSITY = _MATERIALS_DENSITIES['Steel']
5353
5454
55class Factory:55class Factory:
56    """Create and manage materials and alloys."""56    """Create and manage materials and alloys."""
5757
58    _MATERIALS_CREATED = {58    _MATERIALS_CREATED = {
59        'Concrete': Concrete,59        'Concrete': Concrete,
60        'Brick': Brick,60        'Brick': Brick,
61        'Stone': Stone,61        'Stone': Stone,
62        'Wood': Wood,62        'Wood': Wood,
63        'Steel': Steel,63        'Steel': Steel,
64    }64    }
6565
66    all_created_materials = []66    all_created_materials = []
6767
68    def __init__(self):68    def __init__(self):
69        self.materials_created_by_instance = []69        self.materials_created_by_instance = []
7070
71    def __call__(self, *args, **kwargs):71    def __call__(self, *args, **kwargs):
72        """Enable the factory instance to be called."""72        """Enable the factory instance to be called."""
73        if len(args) > 0 and len(kwargs) > 0:73        if len(args) > 0 and len(kwargs) > 0:
74            raise ValueError('One type of arguments are allowed.')74            raise ValueError('One type of arguments are allowed.')
75        elif (len(args), len(kwargs)) == (0, 0):75        elif (len(args), len(kwargs)) == (0, 0):
76            raise ValueError('No arguments found.')76            raise ValueError('No arguments found.')
7777
78        if len(args) > 0:78        if len(args) > 0:
79            return self.positional_call(*args)79            return self.positional_call(*args)
80        return self.keyword_call(**kwargs)80        return self.keyword_call(**kwargs)
8181
82    def positional_call(self, *args):82    def positional_call(self, *args):
83        """Handle creation of alloys from positional arguments."""83        """Handle creation of alloys from positional arguments."""
84        args = [arg[0] if isinstance(arg, tuple) else arg for arg in args]84        args = [arg[0] if isinstance(arg, tuple) else arg for arg in args]
85        for material in args:85        for material in args:
86            material.validate()86            material.validate()
87            material._is_valid = False87            material._is_valid = False
8888
89        base_materials = []89        base_materials = []
90        for material in args:90        for material in args:
91            if hasattr(material, '_base_materials'):91            if hasattr(material, '_base_materials'):
92                base_materials.extend(material._base_materials)92                base_materials.extend(material._base_materials)
93            else:93            else:
94                base_materials.append(type(material).__name__)94                base_materials.append(type(material).__name__)
9595
96        unique_base_materials = sorted(set(base_materials))96        unique_base_materials = sorted(set(base_materials))
9797
98        alloy_name = '_'.join(unique_base_materials)98        alloy_name = '_'.join(unique_base_materials)
99        alloy_density = sum(_MATERIALS_DENSITIES[material] for material in unique_base_materials) / len(unique_base_materials)99        alloy_density = sum(_MATERIALS_DENSITIES[material] for material in unique_base_materials) / len(unique_base_materials)
100        alloy_mass = sum(material.mass for material in args)100        alloy_mass = sum(material.mass for material in args)
101101
102        if alloy_name in self._MATERIALS_CREATED:102        if alloy_name in self._MATERIALS_CREATED:
103            alloy_class = self._MATERIALS_CREATED[alloy_name]103            alloy_class = self._MATERIALS_CREATED[alloy_name]
104        else:104        else:
105            alloy_class = self.create_alloy_class(alloy_name, alloy_density, unique_base_materials)105            alloy_class = self.create_alloy_class(alloy_name, alloy_density, unique_base_materials)
t106            _MATERIALS_DENSITIES[alloy_name] = alloy_densityt
107            106            
108        alloy_instance = alloy_class(alloy_mass)107        alloy_instance = alloy_class(alloy_mass)
109        self.materials_created_by_instance.append(alloy_instance)108        self.materials_created_by_instance.append(alloy_instance)
110        Factory.all_created_materials.append(alloy_instance)109        Factory.all_created_materials.append(alloy_instance)
111110
112        return alloy_instance111        return alloy_instance
113112
114    def create_alloy_class(self, alloy_name, alloy_density, base_materials):113    def create_alloy_class(self, alloy_name, alloy_density, base_materials):
115        """Dynamically create a class for an alloy."""114        """Dynamically create a class for an alloy."""
116        alloy_class = type(115        alloy_class = type(
117            alloy_name,116            alloy_name,
118            (Material,),117            (Material,),
119            {118            {
120                '_DENSITY': alloy_density,119                '_DENSITY': alloy_density,
121                '_base_materials': base_materials,120                '_base_materials': base_materials,
122            }121            }
123        )122        )
124123
125        self._MATERIALS_CREATED[alloy_name] = alloy_class124        self._MATERIALS_CREATED[alloy_name] = alloy_class
126        _MATERIALS_DENSITIES[alloy_name] = alloy_density125        _MATERIALS_DENSITIES[alloy_name] = alloy_density
127        return alloy_class126        return alloy_class
128127
129    def keyword_call(self, **kwargs):128    def keyword_call(self, **kwargs):
130        """Handle creation of materials from keyword arguments."""129        """Handle creation of materials from keyword arguments."""
131        material_instances = []130        material_instances = []
132        for material, mass in kwargs.items():131        for material, mass in kwargs.items():
133            if material not in self._MATERIALS_CREATED:132            if material not in self._MATERIALS_CREATED:
134                raise ValueError('Not valid material found.')133                raise ValueError('Not valid material found.')
135134
136            material_instance = self._MATERIALS_CREATED[material](mass)135            material_instance = self._MATERIALS_CREATED[material](mass)
137            material_instances.append(material_instance)136            material_instances.append(material_instance)
138            self.materials_created_by_instance.append(material_instance) 137            self.materials_created_by_instance.append(material_instance) 
139            self.all_created_materials.append(material_instance)138            self.all_created_materials.append(material_instance)
140139
141        return tuple(material_instances)140        return tuple(material_instances)
142141
143    def can_build(self, target):142    def can_build(self, target):
144        """Check if the factory's materials can build a wall of target volume."""143        """Check if the factory's materials can build a wall of target volume."""
145        valid_materials = [144        valid_materials = [
146            material for material in self.materials_created_by_instance if material._is_valid145            material for material in self.materials_created_by_instance if material._is_valid
147        ]146        ]
148        147        
149        volume_sum = sum(material.volume for material in valid_materials)148        volume_sum = sum(material.volume for material in valid_materials)
150        return volume_sum >= target149        return volume_sum >= target
151150
152    @classmethod151    @classmethod
153    def can_build_together(cls, target):152    def can_build_together(cls, target):
154        """Check if all factories together can build a wall of target volume."""153        """Check if all factories together can build a wall of target volume."""
155        valid_materials = [154        valid_materials = [
156            material for material in cls.all_created_materials if material._is_valid155            material for material in cls.all_created_materials if material._is_valid
157        ]156        ]
158        157        
159        alloy_materials = set(158        alloy_materials = set(
160            material for material in cls.all_created_materials if not material._is_valid159            material for material in cls.all_created_materials if not material._is_valid
161        )160        )
162       161       
163        final_valid_materials = [material for material in valid_materials if material not in alloy_materials]162        final_valid_materials = [material for material in valid_materials if material not in alloy_materials]
164        total_volume = sum(material.volume for material in final_valid_materials)163        total_volume = sum(material.volume for material in final_valid_materials)
165        return total_volume >= target164        return total_volume >= target
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1_MATERIALS_DENSITIES = {f1_MATERIALS_DENSITIES = {
2    'Concrete': 2500,2    'Concrete': 2500,
3    'Brick': 2000,3    'Brick': 2000,
4    'Stone': 1600,4    'Stone': 1600,
5    'Wood': 600,5    'Wood': 600,
6    'Steel': 7700,6    'Steel': 7700,
7}7}
88
9class Material:9class Material:
10    """Base class for materials with mass and density."""10    """Base class for materials with mass and density."""
1111
12    _DENSITY = 112    _DENSITY = 1
1313
14    def __init__(self, mass):14    def __init__(self, mass):
15        """Initialize the material with a given mass."""15        """Initialize the material with a given mass."""
16        self.mass = mass16        self.mass = mass
17        self._is_valid = True17        self._is_valid = True
1818
19    @property19    @property
20    def volume(self):20    def volume(self):
21        """Calculate the volume of the material."""21        """Calculate the volume of the material."""
22        return self.mass / self._DENSITY22        return self.mass / self._DENSITY
2323
24    def validate(self):24    def validate(self):
25        """Check if the material is still valid for use."""25        """Check if the material is still valid for use."""
26        if not self._is_valid:26        if not self._is_valid:
27            raise AssertionError('Not valid material found.')27            raise AssertionError('Not valid material found.')
2828
2929
30class Concrete(Material):30class Concrete(Material):
31    """Concrete material with predefined density."""31    """Concrete material with predefined density."""
32    _DENSITY = _MATERIALS_DENSITIES['Concrete']32    _DENSITY = _MATERIALS_DENSITIES['Concrete']
3333
3434
35class Brick(Material):35class Brick(Material):
36    """Brick material with predefined density."""36    """Brick material with predefined density."""
37    _DENSITY = _MATERIALS_DENSITIES['Brick']37    _DENSITY = _MATERIALS_DENSITIES['Brick']
3838
3939
40class Stone(Material):40class Stone(Material):
41    """Stone material with predefined density."""41    """Stone material with predefined density."""
42    _DENSITY = _MATERIALS_DENSITIES['Stone']42    _DENSITY = _MATERIALS_DENSITIES['Stone']
4343
4444
45class Wood(Material):45class Wood(Material):
46    """Wood material with predefined density."""46    """Wood material with predefined density."""
47    _DENSITY = _MATERIALS_DENSITIES['Wood']47    _DENSITY = _MATERIALS_DENSITIES['Wood']
4848
4949
50class Steel(Material):50class Steel(Material):
51    """Steel material with predefined density."""51    """Steel material with predefined density."""
52    _DENSITY = _MATERIALS_DENSITIES['Steel']52    _DENSITY = _MATERIALS_DENSITIES['Steel']
5353
5454
55class Factory:55class Factory:
56    """Create and manage materials and alloys."""56    """Create and manage materials and alloys."""
5757
58    _MATERIALS_CREATED = {58    _MATERIALS_CREATED = {
59        'Concrete': Concrete,59        'Concrete': Concrete,
60        'Brick': Brick,60        'Brick': Brick,
61        'Stone': Stone,61        'Stone': Stone,
62        'Wood': Wood,62        'Wood': Wood,
63        'Steel': Steel,63        'Steel': Steel,
64    }64    }
6565
66    all_created_materials = []66    all_created_materials = []
6767
68    def __init__(self):68    def __init__(self):
69        self.materials_created_by_instance = []69        self.materials_created_by_instance = []
7070
71    def __call__(self, *args, **kwargs):71    def __call__(self, *args, **kwargs):
72        """Enable the factory instance to be called."""72        """Enable the factory instance to be called."""
73        if len(args) > 0 and len(kwargs) > 0:73        if len(args) > 0 and len(kwargs) > 0:
74            raise ValueError('One type of arguments are allowed.')74            raise ValueError('One type of arguments are allowed.')
75        elif (len(args), len(kwargs)) == (0, 0):75        elif (len(args), len(kwargs)) == (0, 0):
76            raise ValueError('No arguments found.')76            raise ValueError('No arguments found.')
7777
78        if len(args) > 0:78        if len(args) > 0:
79            return self.positional_call(*args)79            return self.positional_call(*args)
80        return self.keyword_call(**kwargs)80        return self.keyword_call(**kwargs)
8181
82    def positional_call(self, *args):82    def positional_call(self, *args):
83        """Handle creation of alloys from positional arguments."""83        """Handle creation of alloys from positional arguments."""
84        args = [arg[0] if isinstance(arg, tuple) else arg for arg in args]84        args = [arg[0] if isinstance(arg, tuple) else arg for arg in args]
85        for material in args:85        for material in args:
86            material.validate()86            material.validate()
87            material._is_valid = False87            material._is_valid = False
8888
89        base_materials = []89        base_materials = []
90        for material in args:90        for material in args:
91            if hasattr(material, '_base_materials'):91            if hasattr(material, '_base_materials'):
92                base_materials.extend(material._base_materials)92                base_materials.extend(material._base_materials)
93            else:93            else:
94                base_materials.append(type(material).__name__)94                base_materials.append(type(material).__name__)
9595
96        unique_base_materials = sorted(set(base_materials))96        unique_base_materials = sorted(set(base_materials))
9797
98        alloy_name = '_'.join(unique_base_materials)98        alloy_name = '_'.join(unique_base_materials)
99        alloy_density = sum(_MATERIALS_DENSITIES[material] for material in unique_base_materials) / len(unique_base_materials)99        alloy_density = sum(_MATERIALS_DENSITIES[material] for material in unique_base_materials) / len(unique_base_materials)
100        alloy_mass = sum(material.mass for material in args)100        alloy_mass = sum(material.mass for material in args)
101101
102        if alloy_name in self._MATERIALS_CREATED:102        if alloy_name in self._MATERIALS_CREATED:
103            alloy_class = self._MATERIALS_CREATED[alloy_name]103            alloy_class = self._MATERIALS_CREATED[alloy_name]
104        else:104        else:
105            alloy_class = self.create_alloy_class(alloy_name, alloy_density, unique_base_materials)105            alloy_class = self.create_alloy_class(alloy_name, alloy_density, unique_base_materials)
n106 n106            _MATERIALS_DENSITIES[alloy_name] = alloy_density
107            
107        alloy_instance = alloy_class(alloy_mass)108        alloy_instance = alloy_class(alloy_mass)
108        self.materials_created_by_instance.append(alloy_instance)109        self.materials_created_by_instance.append(alloy_instance)
109        Factory.all_created_materials.append(alloy_instance)110        Factory.all_created_materials.append(alloy_instance)
110111
111        return alloy_instance112        return alloy_instance
112113
113    def create_alloy_class(self, alloy_name, alloy_density, base_materials):114    def create_alloy_class(self, alloy_name, alloy_density, base_materials):
114        """Dynamically create a class for an alloy."""115        """Dynamically create a class for an alloy."""
115        alloy_class = type(116        alloy_class = type(
116            alloy_name,117            alloy_name,
117            (Material,),118            (Material,),
118            {119            {
119                '_DENSITY': alloy_density,120                '_DENSITY': alloy_density,
120                '_base_materials': base_materials,121                '_base_materials': base_materials,
121            }122            }
122        )123        )
123124
124        self._MATERIALS_CREATED[alloy_name] = alloy_class125        self._MATERIALS_CREATED[alloy_name] = alloy_class
125        _MATERIALS_DENSITIES[alloy_name] = alloy_density126        _MATERIALS_DENSITIES[alloy_name] = alloy_density
126        return alloy_class127        return alloy_class
127128
128    def keyword_call(self, **kwargs):129    def keyword_call(self, **kwargs):
129        """Handle creation of materials from keyword arguments."""130        """Handle creation of materials from keyword arguments."""
130        material_instances = []131        material_instances = []
131        for material, mass in kwargs.items():132        for material, mass in kwargs.items():
132            if material not in self._MATERIALS_CREATED:133            if material not in self._MATERIALS_CREATED:
133                raise ValueError('Not valid material found.')134                raise ValueError('Not valid material found.')
134135
135            material_instance = self._MATERIALS_CREATED[material](mass)136            material_instance = self._MATERIALS_CREATED[material](mass)
136            material_instances.append(material_instance)137            material_instances.append(material_instance)
nn138            self.materials_created_by_instance.append(material_instance) 
139            self.all_created_materials.append(material_instance)
137140
138        return tuple(material_instances)141        return tuple(material_instances)
139142
140    def can_build(self, target):143    def can_build(self, target):
141        """Check if the factory's materials can build a wall of target volume."""144        """Check if the factory's materials can build a wall of target volume."""
n142        volume_sum = sum(n145        valid_materials = [
143            material.volume for material in self.materials_created_by_instance146            material for material in self.materials_created_by_instance if material._is_valid
147        ]
144        )148        
149        volume_sum = sum(material.volume for material in valid_materials)
145        return volume_sum >= target150        return volume_sum >= target
146151
147    @classmethod152    @classmethod
148    def can_build_together(cls, target):153    def can_build_together(cls, target):
149        """Check if all factories together can build a wall of target volume."""154        """Check if all factories together can build a wall of target volume."""
n150        volume_sum = sum(n155        valid_materials = [
151            material.volume for material in cls.all_created_materials 156            material for material in cls.all_created_materials if material._is_valid
157        ]
158        
159        alloy_materials = set(
160            material for material in cls.all_created_materials if not material._is_valid
152        )161        )
tt162       
163        final_valid_materials = [material for material in valid_materials if material not in alloy_materials]
164        total_volume = sum(material.volume for material in final_valid_materials)
153        return volume_sum >= target165        return total_volume >= target
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1_MATERIALS_DENSITIES = {f1_MATERIALS_DENSITIES = {
2    'Concrete': 2500,2    'Concrete': 2500,
3    'Brick': 2000,3    'Brick': 2000,
4    'Stone': 1600,4    'Stone': 1600,
5    'Wood': 600,5    'Wood': 600,
6    'Steel': 7700,6    'Steel': 7700,
7}7}
88
9class Material:9class Material:
10    """Base class for materials with mass and density."""10    """Base class for materials with mass and density."""
1111
12    _DENSITY = 112    _DENSITY = 1
1313
14    def __init__(self, mass):14    def __init__(self, mass):
15        """Initialize the material with a given mass."""15        """Initialize the material with a given mass."""
16        self.mass = mass16        self.mass = mass
17        self._is_valid = True17        self._is_valid = True
1818
19    @property19    @property
20    def volume(self):20    def volume(self):
21        """Calculate the volume of the material."""21        """Calculate the volume of the material."""
22        return self.mass / self._DENSITY22        return self.mass / self._DENSITY
2323
24    def validate(self):24    def validate(self):
25        """Check if the material is still valid for use."""25        """Check if the material is still valid for use."""
26        if not self._is_valid:26        if not self._is_valid:
27            raise AssertionError('Not valid material found.')27            raise AssertionError('Not valid material found.')
2828
2929
30class Concrete(Material):30class Concrete(Material):
31    """Concrete material with predefined density."""31    """Concrete material with predefined density."""
32    _DENSITY = _MATERIALS_DENSITIES['Concrete']32    _DENSITY = _MATERIALS_DENSITIES['Concrete']
3333
3434
35class Brick(Material):35class Brick(Material):
36    """Brick material with predefined density."""36    """Brick material with predefined density."""
37    _DENSITY = _MATERIALS_DENSITIES['Brick']37    _DENSITY = _MATERIALS_DENSITIES['Brick']
3838
3939
40class Stone(Material):40class Stone(Material):
41    """Stone material with predefined density."""41    """Stone material with predefined density."""
42    _DENSITY = _MATERIALS_DENSITIES['Stone']42    _DENSITY = _MATERIALS_DENSITIES['Stone']
4343
4444
45class Wood(Material):45class Wood(Material):
46    """Wood material with predefined density."""46    """Wood material with predefined density."""
47    _DENSITY = _MATERIALS_DENSITIES['Wood']47    _DENSITY = _MATERIALS_DENSITIES['Wood']
4848
4949
50class Steel(Material):50class Steel(Material):
51    """Steel material with predefined density."""51    """Steel material with predefined density."""
52    _DENSITY = _MATERIALS_DENSITIES['Steel']52    _DENSITY = _MATERIALS_DENSITIES['Steel']
5353
5454
55class Factory:55class Factory:
56    """Create and manage materials and alloys."""56    """Create and manage materials and alloys."""
5757
58    _MATERIALS_CREATED = {58    _MATERIALS_CREATED = {
59        'Concrete': Concrete,59        'Concrete': Concrete,
60        'Brick': Brick,60        'Brick': Brick,
61        'Stone': Stone,61        'Stone': Stone,
62        'Wood': Wood,62        'Wood': Wood,
63        'Steel': Steel,63        'Steel': Steel,
64    }64    }
6565
66    all_created_materials = []66    all_created_materials = []
6767
68    def __init__(self):68    def __init__(self):
69        self.materials_created_by_instance = []69        self.materials_created_by_instance = []
7070
71    def __call__(self, *args, **kwargs):71    def __call__(self, *args, **kwargs):
72        """Enable the factory instance to be called."""72        """Enable the factory instance to be called."""
73        if len(args) > 0 and len(kwargs) > 0:73        if len(args) > 0 and len(kwargs) > 0:
74            raise ValueError('One type of arguments are allowed.')74            raise ValueError('One type of arguments are allowed.')
75        elif (len(args), len(kwargs)) == (0, 0):75        elif (len(args), len(kwargs)) == (0, 0):
76            raise ValueError('No arguments found.')76            raise ValueError('No arguments found.')
7777
78        if len(args) > 0:78        if len(args) > 0:
79            return self.positional_call(*args)79            return self.positional_call(*args)
80        return self.keyword_call(**kwargs)80        return self.keyword_call(**kwargs)
8181
82    def positional_call(self, *args):82    def positional_call(self, *args):
83        """Handle creation of alloys from positional arguments."""83        """Handle creation of alloys from positional arguments."""
84        args = [arg[0] if isinstance(arg, tuple) else arg for arg in args]84        args = [arg[0] if isinstance(arg, tuple) else arg for arg in args]
85        for material in args:85        for material in args:
86            material.validate()86            material.validate()
87            material._is_valid = False87            material._is_valid = False
8888
89        base_materials = []89        base_materials = []
90        for material in args:90        for material in args:
91            if hasattr(material, '_base_materials'):91            if hasattr(material, '_base_materials'):
92                base_materials.extend(material._base_materials)92                base_materials.extend(material._base_materials)
93            else:93            else:
94                base_materials.append(type(material).__name__)94                base_materials.append(type(material).__name__)
9595
96        unique_base_materials = sorted(set(base_materials))96        unique_base_materials = sorted(set(base_materials))
9797
98        alloy_name = '_'.join(unique_base_materials)98        alloy_name = '_'.join(unique_base_materials)
99        alloy_density = sum(_MATERIALS_DENSITIES[material] for material in unique_base_materials) / len(unique_base_materials)99        alloy_density = sum(_MATERIALS_DENSITIES[material] for material in unique_base_materials) / len(unique_base_materials)
100        alloy_mass = sum(material.mass for material in args)100        alloy_mass = sum(material.mass for material in args)
101101
102        if alloy_name in self._MATERIALS_CREATED:102        if alloy_name in self._MATERIALS_CREATED:
103            alloy_class = self._MATERIALS_CREATED[alloy_name]103            alloy_class = self._MATERIALS_CREATED[alloy_name]
104        else:104        else:
105            alloy_class = self.create_alloy_class(alloy_name, alloy_density, unique_base_materials)105            alloy_class = self.create_alloy_class(alloy_name, alloy_density, unique_base_materials)
106106
107        alloy_instance = alloy_class(alloy_mass)107        alloy_instance = alloy_class(alloy_mass)
108        self.materials_created_by_instance.append(alloy_instance)108        self.materials_created_by_instance.append(alloy_instance)
109        Factory.all_created_materials.append(alloy_instance)109        Factory.all_created_materials.append(alloy_instance)
110110
111        return alloy_instance111        return alloy_instance
112112
113    def create_alloy_class(self, alloy_name, alloy_density, base_materials):113    def create_alloy_class(self, alloy_name, alloy_density, base_materials):
114        """Dynamically create a class for an alloy."""114        """Dynamically create a class for an alloy."""
115        alloy_class = type(115        alloy_class = type(
116            alloy_name,116            alloy_name,
117            (Material,),117            (Material,),
118            {118            {
119                '_DENSITY': alloy_density,119                '_DENSITY': alloy_density,
120                '_base_materials': base_materials,120                '_base_materials': base_materials,
121            }121            }
122        )122        )
123123
124        self._MATERIALS_CREATED[alloy_name] = alloy_class124        self._MATERIALS_CREATED[alloy_name] = alloy_class
125        _MATERIALS_DENSITIES[alloy_name] = alloy_density125        _MATERIALS_DENSITIES[alloy_name] = alloy_density
126        return alloy_class126        return alloy_class
127127
128    def keyword_call(self, **kwargs):128    def keyword_call(self, **kwargs):
129        """Handle creation of materials from keyword arguments."""129        """Handle creation of materials from keyword arguments."""
130        material_instances = []130        material_instances = []
131        for material, mass in kwargs.items():131        for material, mass in kwargs.items():
132            if material not in self._MATERIALS_CREATED:132            if material not in self._MATERIALS_CREATED:
133                raise ValueError('Not valid material found.')133                raise ValueError('Not valid material found.')
134134
135            material_instance = self._MATERIALS_CREATED[material](mass)135            material_instance = self._MATERIALS_CREATED[material](mass)
136            material_instances.append(material_instance)136            material_instances.append(material_instance)
137137
138        return tuple(material_instances)138        return tuple(material_instances)
139139
140    def can_build(self, target):140    def can_build(self, target):
141        """Check if the factory's materials can build a wall of target volume."""141        """Check if the factory's materials can build a wall of target volume."""
142        volume_sum = sum(142        volume_sum = sum(
n143            material.volume for material in self.materials_created_by_instance if material._is_validn143            material.volume for material in self.materials_created_by_instance
144        )144        )
145        return volume_sum >= target145        return volume_sum >= target
146146
147    @classmethod147    @classmethod
148    def can_build_together(cls, target):148    def can_build_together(cls, target):
149        """Check if all factories together can build a wall of target volume."""149        """Check if all factories together can build a wall of target volume."""
150        volume_sum = sum(150        volume_sum = sum(
t151            material.volume for material in cls.all_created_materials if material._is_validt151            material.volume for material in cls.all_created_materials 
152        )152        )
153        return volume_sum >= target153        return volume_sum >= target
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1_MATERIALS_DENSITIES = {f1_MATERIALS_DENSITIES = {
2    'Concrete': 2500,2    'Concrete': 2500,
3    'Brick': 2000,3    'Brick': 2000,
4    'Stone': 1600,4    'Stone': 1600,
5    'Wood': 600,5    'Wood': 600,
6    'Steel': 7700,6    'Steel': 7700,
7}7}
88
9class Material:9class Material:
10    """Base class for materials with mass and density."""10    """Base class for materials with mass and density."""
1111
12    _DENSITY = 112    _DENSITY = 1
1313
14    def __init__(self, mass):14    def __init__(self, mass):
15        """Initialize the material with a given mass."""15        """Initialize the material with a given mass."""
16        self.mass = mass16        self.mass = mass
17        self._is_valid = True17        self._is_valid = True
1818
19    @property19    @property
20    def volume(self):20    def volume(self):
21        """Calculate the volume of the material."""21        """Calculate the volume of the material."""
22        return self.mass / self._DENSITY22        return self.mass / self._DENSITY
2323
24    def validate(self):24    def validate(self):
25        """Check if the material is still valid for use."""25        """Check if the material is still valid for use."""
26        if not self._is_valid:26        if not self._is_valid:
27            raise AssertionError('Not valid material found.')27            raise AssertionError('Not valid material found.')
2828
2929
30class Concrete(Material):30class Concrete(Material):
31    """Concrete material with predefined density."""31    """Concrete material with predefined density."""
32    _DENSITY = _MATERIALS_DENSITIES['Concrete']32    _DENSITY = _MATERIALS_DENSITIES['Concrete']
3333
3434
35class Brick(Material):35class Brick(Material):
36    """Brick material with predefined density."""36    """Brick material with predefined density."""
37    _DENSITY = _MATERIALS_DENSITIES['Brick']37    _DENSITY = _MATERIALS_DENSITIES['Brick']
3838
3939
40class Stone(Material):40class Stone(Material):
41    """Stone material with predefined density."""41    """Stone material with predefined density."""
42    _DENSITY = _MATERIALS_DENSITIES['Stone']42    _DENSITY = _MATERIALS_DENSITIES['Stone']
4343
4444
45class Wood(Material):45class Wood(Material):
46    """Wood material with predefined density."""46    """Wood material with predefined density."""
47    _DENSITY = _MATERIALS_DENSITIES['Wood']47    _DENSITY = _MATERIALS_DENSITIES['Wood']
4848
4949
50class Steel(Material):50class Steel(Material):
51    """Steel material with predefined density."""51    """Steel material with predefined density."""
52    _DENSITY = _MATERIALS_DENSITIES['Steel']52    _DENSITY = _MATERIALS_DENSITIES['Steel']
5353
5454
55class Factory:55class Factory:
56    """Create and manage materials and alloys."""56    """Create and manage materials and alloys."""
5757
58    _MATERIALS_CREATED = {58    _MATERIALS_CREATED = {
59        'Concrete': Concrete,59        'Concrete': Concrete,
60        'Brick': Brick,60        'Brick': Brick,
61        'Stone': Stone,61        'Stone': Stone,
62        'Wood': Wood,62        'Wood': Wood,
63        'Steel': Steel,63        'Steel': Steel,
64    }64    }
6565
66    all_created_materials = []66    all_created_materials = []
6767
68    def __init__(self):68    def __init__(self):
69        self.materials_created_by_instance = []69        self.materials_created_by_instance = []
7070
71    def __call__(self, *args, **kwargs):71    def __call__(self, *args, **kwargs):
72        """Enable the factory instance to be called."""72        """Enable the factory instance to be called."""
73        if len(args) > 0 and len(kwargs) > 0:73        if len(args) > 0 and len(kwargs) > 0:
74            raise ValueError('One type of arguments are allowed.')74            raise ValueError('One type of arguments are allowed.')
75        elif (len(args), len(kwargs)) == (0, 0):75        elif (len(args), len(kwargs)) == (0, 0):
76            raise ValueError('No arguments found.')76            raise ValueError('No arguments found.')
7777
78        if len(args) > 0:78        if len(args) > 0:
79            return self.positional_call(*args)79            return self.positional_call(*args)
80        return self.keyword_call(**kwargs)80        return self.keyword_call(**kwargs)
8181
82    def positional_call(self, *args):82    def positional_call(self, *args):
83        """Handle creation of alloys from positional arguments."""83        """Handle creation of alloys from positional arguments."""
84        args = [arg[0] if isinstance(arg, tuple) else arg for arg in args]84        args = [arg[0] if isinstance(arg, tuple) else arg for arg in args]
85        for material in args:85        for material in args:
86            material.validate()86            material.validate()
87            material._is_valid = False87            material._is_valid = False
8888
89        base_materials = []89        base_materials = []
90        for material in args:90        for material in args:
91            if hasattr(material, '_base_materials'):91            if hasattr(material, '_base_materials'):
92                base_materials.extend(material._base_materials)92                base_materials.extend(material._base_materials)
93            else:93            else:
94                base_materials.append(type(material).__name__)94                base_materials.append(type(material).__name__)
9595
96        unique_base_materials = sorted(set(base_materials))96        unique_base_materials = sorted(set(base_materials))
9797
98        alloy_name = '_'.join(unique_base_materials)98        alloy_name = '_'.join(unique_base_materials)
99        alloy_density = sum(_MATERIALS_DENSITIES[material] for material in unique_base_materials) / len(unique_base_materials)99        alloy_density = sum(_MATERIALS_DENSITIES[material] for material in unique_base_materials) / len(unique_base_materials)
100        alloy_mass = sum(material.mass for material in args)100        alloy_mass = sum(material.mass for material in args)
101101
102        if alloy_name in self._MATERIALS_CREATED:102        if alloy_name in self._MATERIALS_CREATED:
103            alloy_class = self._MATERIALS_CREATED[alloy_name]103            alloy_class = self._MATERIALS_CREATED[alloy_name]
104        else:104        else:
105            alloy_class = self.create_alloy_class(alloy_name, alloy_density, unique_base_materials)105            alloy_class = self.create_alloy_class(alloy_name, alloy_density, unique_base_materials)
106106
107        alloy_instance = alloy_class(alloy_mass)107        alloy_instance = alloy_class(alloy_mass)
108        self.materials_created_by_instance.append(alloy_instance)108        self.materials_created_by_instance.append(alloy_instance)
109        Factory.all_created_materials.append(alloy_instance)109        Factory.all_created_materials.append(alloy_instance)
110110
111        return alloy_instance111        return alloy_instance
112112
113    def create_alloy_class(self, alloy_name, alloy_density, base_materials):113    def create_alloy_class(self, alloy_name, alloy_density, base_materials):
114        """Dynamically create a class for an alloy."""114        """Dynamically create a class for an alloy."""
115        alloy_class = type(115        alloy_class = type(
116            alloy_name,116            alloy_name,
117            (Material,),117            (Material,),
118            {118            {
119                '_DENSITY': alloy_density,119                '_DENSITY': alloy_density,
120                '_base_materials': base_materials,120                '_base_materials': base_materials,
121            }121            }
122        )122        )
123123
124        self._MATERIALS_CREATED[alloy_name] = alloy_class124        self._MATERIALS_CREATED[alloy_name] = alloy_class
125        _MATERIALS_DENSITIES[alloy_name] = alloy_density125        _MATERIALS_DENSITIES[alloy_name] = alloy_density
126        return alloy_class126        return alloy_class
127127
128    def keyword_call(self, **kwargs):128    def keyword_call(self, **kwargs):
129        """Handle creation of materials from keyword arguments."""129        """Handle creation of materials from keyword arguments."""
130        material_instances = []130        material_instances = []
131        for material, mass in kwargs.items():131        for material, mass in kwargs.items():
132            if material not in self._MATERIALS_CREATED:132            if material not in self._MATERIALS_CREATED:
133                raise ValueError('Not valid material found.')133                raise ValueError('Not valid material found.')
134134
135            material_instance = self._MATERIALS_CREATED[material](mass)135            material_instance = self._MATERIALS_CREATED[material](mass)
136            material_instances.append(material_instance)136            material_instances.append(material_instance)
t137            self.materials_created_by_instance.append(material_instance)t
138            Factory.all_created_materials.append(material_instance)
139137
140        return tuple(material_instances)138        return tuple(material_instances)
141139
142    def can_build(self, target):140    def can_build(self, target):
143        """Check if the factory's materials can build a wall of target volume."""141        """Check if the factory's materials can build a wall of target volume."""
144        volume_sum = sum(142        volume_sum = sum(
145            material.volume for material in self.materials_created_by_instance if material._is_valid143            material.volume for material in self.materials_created_by_instance if material._is_valid
146        )144        )
147        return volume_sum >= target145        return volume_sum >= target
148146
149    @classmethod147    @classmethod
150    def can_build_together(cls, target):148    def can_build_together(cls, target):
151        """Check if all factories together can build a wall of target volume."""149        """Check if all factories together can build a wall of target volume."""
152        volume_sum = sum(150        volume_sum = sum(
153            material.volume for material in cls.all_created_materials if material._is_valid151            material.volume for material in cls.all_created_materials if material._is_valid
154        )152        )
155        return volume_sum >= target153        return volume_sum >= target
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op