Домашни > Another brick in the wall > Решения > Решението на Ева Ганчева

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

9 точки общо

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

  1class Material:
  2    """Class, that represent material"""
  3    density = 0
  4
  5    def __init__(self, mass):
  6        """Initialize Material instance"""
  7        self.mass = mass
  8        self.used = False
  9
 10    @property
 11    def volume(self):
 12        """Calculate the volume"""
 13        return self.mass / self.density
 14
 15    def mark_as_used(self):
 16        """Mark the material as used"""
 17        self.used = True
 18
 19
 20class Concrete(Material):
 21    """Class, that represent Concrete material"""
 22    density = 2500
 23
 24
 25class Brick(Material):
 26    """Class, that represent Brick material"""
 27    density = 2000
 28
 29
 30class Stone(Material):
 31    """Class, that represent Stone material"""
 32    density = 1600
 33
 34
 35class Wood(Material):
 36    """Class, that represent Wood material"""
 37    density = 600
 38
 39
 40class Steel(Material):
 41    """Class, that represent Steel material"""
 42    density = 7700
 43
 44
 45class Factory:
 46    """Represent a factory that create and manage materials"""
 47    _shared_classes = {
 48        "Concrete": Concrete,
 49        "Brick": Brick,
 50        "Stone": Stone,
 51        "Wood": Wood,
 52        "Steel": Steel
 53    }
 54    _all_materials = []
 55
 56    def __init__(self):
 57        """Initialize Factory instance"""
 58        self.valid_materials = []
 59
 60    def call_for_kwargs(self, **kwargs):
 61        """Create material from kwargs"""
 62        result = []
 63        for name, mass in kwargs.items():
 64            material = self._get_class_by_name(name)(mass)
 65            result.append(material)
 66        self.valid_materials.extend(result)
 67        self._all_materials.extend(result)
 68        return tuple(result)
 69
 70    @classmethod
 71    def _get_class_by_name(cls, name):
 72        """Get a material class by its name"""
 73        # for clas in cls._shared_classes.values():
 74        #     if clas.__name__ == name:
 75        #         return clas
 76        # raise ValueError("Not existing material")
 77        if name in cls._shared_classes:
 78            return cls._shared_classes[name]
 79        raise ValueError("Not existing material")
 80
 81    def call_for_args(self, *args):
 82        """Combine material from args"""
 83        for arg in args:
 84            if arg.used:
 85                raise AssertionError("This material has already been used.")
 86            arg.mark_as_used()
 87
 88        material_classes = []
 89        mass = 0
 90        for arg in args:
 91            for class_name in type(arg).__name__.split('_'):
 92                material_classes.append(self._get_class_by_name(class_name))
 93            mass += arg.mass
 94        material_classes.sort(key=lambda obj: obj.__name__)
 95        class_name = "_".join([base.__name__ for base in material_classes])
 96        try:
 97            target_class = self._get_class_by_name(class_name)
 98            instance = target_class(mass)
 99            self.valid_materials.append(instance)
100            self._all_materials.append(instance)
101            return instance
102        except ValueError:
103            avg_density = sum(mat.density for mat in material_classes) / len(material_classes)
104            new_class = type(class_name, (Material,), {"density": avg_density})
105            instance = new_class(mass)
106            self.valid_materials.append(instance)
107            self._all_materials.append(instance)
108            self._shared_classes[class_name] = new_class
109            return instance
110
111    def __call__(self, *args, **kwargs):
112        """Create materials"""
113        if (args and kwargs) or (not args and not kwargs):
114            raise ValueError("Wrong arguments")
115        if args:
116            return self.call_for_args(*args)
117        if kwargs:
118            return self.call_for_kwargs(**kwargs)
119
120    def can_build(self, volume_required):
121        """Check if the unused materials in this factory can satisfy a required volume"""
122        total_volume = sum(material.volume for material in self.valid_materials if not material.used)
123        return total_volume >= volume_required
124
125    @classmethod
126    def can_build_together(cls, volume_required):
127        """Check if the unused materials across all factories can satisfy a required volume"""
128        total_volume = sum(material.volume for material in cls._all_materials if not material.used)
129        return total_volume >= volume_required

.....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 116, in __call__
return self.call_for_args(*args)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 85, in call_for_args
raise AssertionError("This material has already been used.")
AssertionError: This material has already been used.

----------------------------------------------------------------------
Ran 10 tests in 0.012s

FAILED (failures=1)

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

f1class Material:f1class Material:
2    """Class, that represent material"""2    """Class, that represent material"""
3    density = 03    density = 0
44
5    def __init__(self, mass):5    def __init__(self, mass):
6        """Initialize Material instance"""6        """Initialize Material instance"""
7        self.mass = mass7        self.mass = mass
8        self.used = False8        self.used = False
99
10    @property10    @property
11    def volume(self):11    def volume(self):
12        """Calculate the volume"""12        """Calculate the volume"""
n13        return float(self.mass / self.density)n13        return self.mass / self.density
1414
15    def mark_as_used(self):15    def mark_as_used(self):
16        """Mark the material as used"""16        """Mark the material as used"""
17        self.used = True17        self.used = True
1818
1919
20class Concrete(Material):20class Concrete(Material):
21    """Class, that represent Concrete material"""21    """Class, that represent Concrete material"""
22    density = 250022    density = 2500
2323
2424
25class Brick(Material):25class Brick(Material):
26    """Class, that represent Brick material"""26    """Class, that represent Brick material"""
27    density = 200027    density = 2000
2828
2929
30class Stone(Material):30class Stone(Material):
31    """Class, that represent Stone material"""31    """Class, that represent Stone material"""
32    density = 160032    density = 1600
3333
3434
35class Wood(Material):35class Wood(Material):
36    """Class, that represent Wood material"""36    """Class, that represent Wood material"""
37    density = 60037    density = 600
3838
3939
40class Steel(Material):40class Steel(Material):
41    """Class, that represent Steel material"""41    """Class, that represent Steel material"""
42    density = 770042    density = 7700
4343
4444
45class Factory:45class Factory:
46    """Represent a factory that create and manage materials"""46    """Represent a factory that create and manage materials"""
47    _shared_classes = {47    _shared_classes = {
48        "Concrete": Concrete,48        "Concrete": Concrete,
49        "Brick": Brick,49        "Brick": Brick,
50        "Stone": Stone,50        "Stone": Stone,
51        "Wood": Wood,51        "Wood": Wood,
52        "Steel": Steel52        "Steel": Steel
53    }53    }
54    _all_materials = []54    _all_materials = []
5555
56    def __init__(self):56    def __init__(self):
57        """Initialize Factory instance"""57        """Initialize Factory instance"""
58        self.valid_materials = []58        self.valid_materials = []
5959
60    def call_for_kwargs(self, **kwargs):60    def call_for_kwargs(self, **kwargs):
61        """Create material from kwargs"""61        """Create material from kwargs"""
62        result = []62        result = []
63        for name, mass in kwargs.items():63        for name, mass in kwargs.items():
64            material = self._get_class_by_name(name)(mass)64            material = self._get_class_by_name(name)(mass)
65            result.append(material)65            result.append(material)
66        self.valid_materials.extend(result)66        self.valid_materials.extend(result)
n67        self.__class__._all_materials.extend(result)n67        self._all_materials.extend(result)
68        return tuple(result)68        return tuple(result)
6969
70    @classmethod70    @classmethod
71    def _get_class_by_name(cls, name):71    def _get_class_by_name(cls, name):
72        """Get a material class by its name"""72        """Get a material class by its name"""
n73        for clas in cls._shared_classes.values():n73        # for clas in cls._shared_classes.values():
74            if clas.__name__ == name:74        #     if clas.__name__ == name:
75                return clas75        #         return clas
76        # raise ValueError("Not existing material")
77        if name in cls._shared_classes:
78            return cls._shared_classes[name]
76        raise ValueError("Not existing material")79        raise ValueError("Not existing material")
7780
78    def call_for_args(self, *args):81    def call_for_args(self, *args):
79        """Combine material from args"""82        """Combine material from args"""
80        for arg in args:83        for arg in args:
81            if arg.used:84            if arg.used:
82                raise AssertionError("This material has already been used.")85                raise AssertionError("This material has already been used.")
83            arg.mark_as_used()86            arg.mark_as_used()
8487
85        material_classes = []88        material_classes = []
86        mass = 089        mass = 0
87        for arg in args:90        for arg in args:
88            for class_name in type(arg).__name__.split('_'):91            for class_name in type(arg).__name__.split('_'):
89                material_classes.append(self._get_class_by_name(class_name))92                material_classes.append(self._get_class_by_name(class_name))
90            mass += arg.mass93            mass += arg.mass
91        material_classes.sort(key=lambda obj: obj.__name__)94        material_classes.sort(key=lambda obj: obj.__name__)
92        class_name = "_".join([base.__name__ for base in material_classes])95        class_name = "_".join([base.__name__ for base in material_classes])
93        try:96        try:
94            target_class = self._get_class_by_name(class_name)97            target_class = self._get_class_by_name(class_name)
95            instance = target_class(mass)98            instance = target_class(mass)
96            self.valid_materials.append(instance)99            self.valid_materials.append(instance)
n97            self.__class__._all_materials.append(instance)n100            self._all_materials.append(instance)
98            return instance101            return instance
99        except ValueError:102        except ValueError:
100            avg_density = sum(mat.density for mat in material_classes) / len(material_classes)103            avg_density = sum(mat.density for mat in material_classes) / len(material_classes)
101            new_class = type(class_name, (Material,), {"density": avg_density})104            new_class = type(class_name, (Material,), {"density": avg_density})
102            instance = new_class(mass)105            instance = new_class(mass)
103            self.valid_materials.append(instance)106            self.valid_materials.append(instance)
t104            self.__class__._all_materials.append(instance)t107            self._all_materials.append(instance)
105            self._shared_classes[class_name] = new_class108            self._shared_classes[class_name] = new_class
106            return instance109            return instance
107110
108    def __call__(self, *args, **kwargs):111    def __call__(self, *args, **kwargs):
109        """Create materials"""112        """Create materials"""
110        if (args and kwargs) or (not args and not kwargs):113        if (args and kwargs) or (not args and not kwargs):
111            raise ValueError("Wrong arguments")114            raise ValueError("Wrong arguments")
112        if args:115        if args:
113            return self.call_for_args(*args)116            return self.call_for_args(*args)
114        if kwargs:117        if kwargs:
115            return self.call_for_kwargs(**kwargs)118            return self.call_for_kwargs(**kwargs)
116119
117    def can_build(self, volume_required):120    def can_build(self, volume_required):
118        """Check if the unused materials in this factory can satisfy a required volume"""121        """Check if the unused materials in this factory can satisfy a required volume"""
119        total_volume = sum(material.volume for material in self.valid_materials if not material.used)122        total_volume = sum(material.volume for material in self.valid_materials if not material.used)
120        return total_volume >= volume_required123        return total_volume >= volume_required
121124
122    @classmethod125    @classmethod
123    def can_build_together(cls, volume_required):126    def can_build_together(cls, volume_required):
124        """Check if the unused materials across all factories can satisfy a required volume"""127        """Check if the unused materials across all factories can satisfy a required volume"""
125        total_volume = sum(material.volume for material in cls._all_materials if not material.used)128        total_volume = sum(material.volume for material in cls._all_materials if not material.used)
126        return total_volume >= volume_required129        return total_volume >= volume_required
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op