Домашни > Another brick in the wall > Решения > Решението на Виктор Бечев

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

10 точки общо

10 успешни теста
0 неуспешни теста
Код (Use sets instead and keep line length consistent)

  1class MaterialType(type):
  2    @property
  3    def name(self):
  4        """Make the class name accessible via "name" for better utility."""
  5        return self.__name__ # self in this case is the _Material class
  6
  7
  8class _Material(metaclass=MaterialType):
  9    """Class that implements all of the materials behaviour."""
 10    density = None # Placeholder
 11    individual_materials = [] # Placeholder
 12
 13    def __init__(self, mass):
 14        self.mass = mass
 15
 16    @property
 17    def name(self):
 18        return self.__class__.__name__
 19
 20    @property
 21    def volume(self):
 22        return self.mass / self.density
 23
 24    @classmethod
 25    def create_composite_material(cls, input_materials):
 26        """Create a new material (type) from multiple existing ones."""
 27        individual_materials = [material
 28                                for input_material in input_materials
 29                                for material in input_material.individual_materials]
 30        new_material_name = "_".join(sorted(material.__name__ for material in individual_materials))
 31        new_material_density = sum(material.density
 32                                   for material in individual_materials) / len(individual_materials)
 33        new_material = cls.create_material(new_material_name, new_material_density)
 34        new_material.individual_materials = individual_materials
 35        return new_material
 36
 37    @classmethod
 38    def create_material(cls, name, density):
 39        """Create a new material (type) based on name and density."""
 40        new_material = MaterialType(name, (cls,), {"density": density})
 41        new_material.individual_materials = [new_material]
 42        return new_material
 43
 44
 45STARTING_MATERIALS = {"Brick": 2000, "Concrete": 2500, "Steel": 7700, "Stone": 1600, "Wood": 600}
 46Brick, Concrete, Steel, Stone, Wood = (_Material.create_material(name, density)
 47                                       for name,density in STARTING_MATERIALS.items())
 48
 49
 50class Factory:
 51    """A factory that produces materials and pieces of a given material."""
 52    existing_materials = {material.name: material for material in (Brick, Concrete, Steel, Stone, Wood)}
 53    expended_material_pieces = set()
 54    factories = []
 55
 56    def __init__(self):
 57        self.produced_material_pieces = set()
 58        self.factories.append(self)
 59
 60    def __call__(self, *args, **kwargs):
 61        """Make an order to the factory."""
 62        if not bool(args) ^ bool(kwargs):
 63            raise ValueError("Ебем ти и вноса.")
 64        if args:
 65            return self.create_new_material(args)
 66        if kwargs:
 67            if any(material not in self.existing_materials for material in kwargs):
 68                raise ValueError("Ебем ти и вноса.")
 69            return self._produce_materials(kwargs)
 70
 71    def create_new_material(self, input_materials):
 72        """Create a new material (type) and register it, return a piece of that material."""
 73        if any(material in self.expended_material_pieces for material in input_materials):
 74            raise AssertionError("Ти кого се опитваш да ментиш?")
 75        self.expended_material_pieces.update(input_materials) # Register the used materials
 76
 77        new_material = _Material.create_composite_material(input_materials)
 78        new_material_mass = sum(material.mass for material in input_materials)
 79        if new_material.name not in self.existing_materials:
 80            self.existing_materials[new_material.name] = new_material # Register the new material
 81        return self._produce_material(new_material.name, new_material_mass)
 82
 83    def _produce_material(self, name, mass):
 84        """Produce a piece of a material and register it's production."""
 85        self.produced_material_pieces.add(production := self.existing_materials[name](mass))
 86        return production
 87
 88    def _produce_materials(self, input_materials):
 89        """Produce pieces of multiple materials."""
 90        return tuple(self._produce_material(name, mass) for name, mass in input_materials.items())
 91
 92    def can_build(self, wall_volume):
 93        """Determine if the factory has produced enough materials to build a wall."""
 94        # A compromise must be made here between getting close to proper line length limits
 95        # and having to define a single "useless" variable
 96        pieces = (piece.volume for piece in self.produced_material_pieces - self.expended_material_pieces)
 97        return sum(pieces) >= wall_volume
 98
 99    @classmethod
100    def can_build_together(cls, wall_volume):
101        """Determine if all factories together have produced enough materials to build a wall."""
102        all_factory_volumes = (piece.volume
103                               for factory in cls.factories
104                               for piece in factory.produced_material_pieces
105                               if piece not in factory.expended_material_pieces)
106        return sum(all_factory_volumes) >= wall_volume

..........
----------------------------------------------------------------------
Ran 10 tests in 0.011s

OK

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

f1class MaterialType(type):f1class MaterialType(type):
2    @property2    @property
3    def name(self):3    def name(self):
4        """Make the class name accessible via "name" for better utility."""4        """Make the class name accessible via "name" for better utility."""
5        return self.__name__ # self in this case is the _Material class5        return self.__name__ # self in this case is the _Material class
66
77
8class _Material(metaclass=MaterialType):8class _Material(metaclass=MaterialType):
9    """Class that implements all of the materials behaviour."""9    """Class that implements all of the materials behaviour."""
10    density = None # Placeholder10    density = None # Placeholder
11    individual_materials = [] # Placeholder11    individual_materials = [] # Placeholder
1212
13    def __init__(self, mass):13    def __init__(self, mass):
14        self.mass = mass14        self.mass = mass
1515
16    @property16    @property
17    def name(self):17    def name(self):
18        return self.__class__.__name__18        return self.__class__.__name__
1919
20    @property20    @property
21    def volume(self):21    def volume(self):
22        return self.mass / self.density22        return self.mass / self.density
2323
24    @classmethod24    @classmethod
25    def create_composite_material(cls, input_materials):25    def create_composite_material(cls, input_materials):
26        """Create a new material (type) from multiple existing ones."""26        """Create a new material (type) from multiple existing ones."""
27        individual_materials = [material27        individual_materials = [material
28                                for input_material in input_materials28                                for input_material in input_materials
29                                for material in input_material.individual_materials]29                                for material in input_material.individual_materials]
30        new_material_name = "_".join(sorted(material.__name__ for material in individual_materials))30        new_material_name = "_".join(sorted(material.__name__ for material in individual_materials))
n31        new_material_density = sum(material.density for material in individual_materials) / len(individual_materials)n31        new_material_density = sum(material.density
32                                   for material in individual_materials) / len(individual_materials)
32        new_material = cls.create_material(new_material_name, new_material_density)33        new_material = cls.create_material(new_material_name, new_material_density)
33        new_material.individual_materials = individual_materials34        new_material.individual_materials = individual_materials
34        return new_material35        return new_material
3536
36    @classmethod37    @classmethod
37    def create_material(cls, name, density):38    def create_material(cls, name, density):
38        """Create a new material (type) based on name and density."""39        """Create a new material (type) based on name and density."""
39        new_material = MaterialType(name, (cls,), {"density": density})40        new_material = MaterialType(name, (cls,), {"density": density})
40        new_material.individual_materials = [new_material]41        new_material.individual_materials = [new_material]
41        return new_material42        return new_material
4243
4344
44STARTING_MATERIALS = {"Brick": 2000, "Concrete": 2500, "Steel": 7700, "Stone": 1600, "Wood": 600}45STARTING_MATERIALS = {"Brick": 2000, "Concrete": 2500, "Steel": 7700, "Stone": 1600, "Wood": 600}
45Brick, Concrete, Steel, Stone, Wood = (_Material.create_material(name, density)46Brick, Concrete, Steel, Stone, Wood = (_Material.create_material(name, density)
46                                       for name,density in STARTING_MATERIALS.items())47                                       for name,density in STARTING_MATERIALS.items())
4748
4849
49class Factory:50class Factory:
50    """A factory that produces materials and pieces of a given material."""51    """A factory that produces materials and pieces of a given material."""
51    existing_materials = {material.name: material for material in (Brick, Concrete, Steel, Stone, Wood)}52    existing_materials = {material.name: material for material in (Brick, Concrete, Steel, Stone, Wood)}
n52    expended_material_pieces = []n53    expended_material_pieces = set()
53    factories = []54    factories = []
5455
55    def __init__(self):56    def __init__(self):
n56        self.produced_material_pieces = []n57        self.produced_material_pieces = set()
57        self.factories.append(self)58        self.factories.append(self)
5859
59    def __call__(self, *args, **kwargs):60    def __call__(self, *args, **kwargs):
60        """Make an order to the factory."""61        """Make an order to the factory."""
61        if not bool(args) ^ bool(kwargs):62        if not bool(args) ^ bool(kwargs):
62            raise ValueError("Ебем ти и вноса.")63            raise ValueError("Ебем ти и вноса.")
63        if args:64        if args:
64            return self.create_new_material(args)65            return self.create_new_material(args)
65        if kwargs:66        if kwargs:
66            if any(material not in self.existing_materials for material in kwargs):67            if any(material not in self.existing_materials for material in kwargs):
67                raise ValueError("Ебем ти и вноса.")68                raise ValueError("Ебем ти и вноса.")
68            return self._produce_materials(kwargs)69            return self._produce_materials(kwargs)
6970
70    def create_new_material(self, input_materials):71    def create_new_material(self, input_materials):
71        """Create a new material (type) and register it, return a piece of that material."""72        """Create a new material (type) and register it, return a piece of that material."""
72        if any(material in self.expended_material_pieces for material in input_materials):73        if any(material in self.expended_material_pieces for material in input_materials):
73            raise AssertionError("Ти кого се опитваш да ментиш?")74            raise AssertionError("Ти кого се опитваш да ментиш?")
n74        self.expended_material_pieces.extend(input_materials) # Register the used materialsn75        self.expended_material_pieces.update(input_materials) # Register the used materials
7576
76        new_material = _Material.create_composite_material(input_materials)77        new_material = _Material.create_composite_material(input_materials)
77        new_material_mass = sum(material.mass for material in input_materials)78        new_material_mass = sum(material.mass for material in input_materials)
78        if new_material.name not in self.existing_materials:79        if new_material.name not in self.existing_materials:
79            self.existing_materials[new_material.name] = new_material # Register the new material80            self.existing_materials[new_material.name] = new_material # Register the new material
80        return self._produce_material(new_material.name, new_material_mass)81        return self._produce_material(new_material.name, new_material_mass)
8182
82    def _produce_material(self, name, mass):83    def _produce_material(self, name, mass):
83        """Produce a piece of a material and register it's production."""84        """Produce a piece of a material and register it's production."""
n84        self.produced_material_pieces.append(production := self.existing_materials[name](mass))n85        self.produced_material_pieces.add(production := self.existing_materials[name](mass))
85        return production86        return production
8687
87    def _produce_materials(self, input_materials):88    def _produce_materials(self, input_materials):
88        """Produce pieces of multiple materials."""89        """Produce pieces of multiple materials."""
89        return tuple(self._produce_material(name, mass) for name, mass in input_materials.items())90        return tuple(self._produce_material(name, mass) for name, mass in input_materials.items())
9091
91    def can_build(self, wall_volume):92    def can_build(self, wall_volume):
92        """Determine if the factory has produced enough materials to build a wall."""93        """Determine if the factory has produced enough materials to build a wall."""
tt94        # A compromise must be made here between getting close to proper line length limits
95        # and having to define a single "useless" variable
93        return sum(piece.volume for piece in self.produced_material_pieces if piece not in self.expended_material_pieces) >= wall_volume96        pieces = (piece.volume for piece in self.produced_material_pieces - self.expended_material_pieces)
97        return sum(pieces) >= wall_volume
9498
95    @classmethod99    @classmethod
96    def can_build_together(cls, wall_volume):100    def can_build_together(cls, wall_volume):
97        """Determine if all factories together have produced enough materials to build a wall."""101        """Determine if all factories together have produced enough materials to build a wall."""
98        all_factory_volumes = (piece.volume102        all_factory_volumes = (piece.volume
99                               for factory in cls.factories103                               for factory in cls.factories
100                               for piece in factory.produced_material_pieces104                               for piece in factory.produced_material_pieces
101                               if piece not in factory.expended_material_pieces)105                               if piece not in factory.expended_material_pieces)
102        return sum(all_factory_volumes) >= wall_volume106        return sum(all_factory_volumes) >= wall_volume
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op