Домашни > Another brick in the wall > Решения > Решението на Василена Станойска

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

10 точки общо

10 успешни теста
0 неуспешни теста
Код

  1class Material:
  2    density = 0
  3    def __init__(self, weight):
  4        self.weight = weight
  5    
  6    @property
  7    def volume(self):
  8        return self.weight / self.density
  9
 10    def _get_class_name(self):
 11        return self.__class__.__name__
 12
 13
 14class Concrete(Material):
 15    density = 2500
 16    
 17    
 18class Brick(Material):
 19    density = 2000
 20
 21
 22class Stone(Material):
 23    density = 1600
 24
 25
 26class Wood(Material):
 27    density = 600
 28
 29
 30class Steel(Material):
 31    density = 7700
 32
 33
 34class Factory:
 35    created_material_classes = {
 36        "Brick": Brick,
 37        "Concrete": Concrete,
 38        "Steel": Steel,
 39        "Stone": Stone,
 40        "Wood": Wood,
 41    }
 42        
 43    used_instances = set()
 44    all_instances = set()
 45
 46    def __init__(self):
 47        self.current_instances = set()
 48    
 49    def _get_base_densities(self, args, processed_classes):
 50        """Get the densities of the base materials used to create the given instances."""
 51        densities = []
 52
 53        for arg in args:
 54            if isinstance(arg, Material):
 55                class_name = arg._get_class_name()
 56                base_classes = class_name.split("_")
 57
 58                for base in base_classes:
 59                    if base not in processed_classes:
 60                        if base in self.created_material_classes:
 61                            densities.append(self.created_material_classes[base].density)
 62                            processed_classes.add(base)
 63                        else:
 64                            raise ValueError(f"Unknown material base: {base}")
 65        return densities
 66
 67    def __call__(self, *args, **kwargs):
 68        if not args and not kwargs:
 69            raise ValueError("Cannot call with no arguments.")
 70        if args and kwargs:
 71            raise ValueError("Cannot mix positional and keyword arguments.")
 72        
 73        if kwargs:
 74            instances = ()
 75            for key, value in kwargs.items():
 76                if key in self.created_material_classes:
 77                    material_class = self.created_material_classes[key]
 78                    instance = material_class(value)
 79                    instances += (instance,)
 80                    
 81                    self.current_instances.add(instance)
 82                    self.all_instances.add(instance)
 83                else:
 84                    raise ValueError(f"Invalid name of keyword argument: {key}")
 85            return instances
 86        
 87        if args:
 88            for arg in args:
 89                if arg in self.used_instances:
 90                    raise AssertionError(f"Instance {arg} has already been used.")
 91                if not any(isinstance(arg, cls) for cls in self.created_material_classes.values()):
 92                    raise ValueError(f"Invalid material instance: {arg}")
 93            
 94            class_name = "_".join(
 95                sorted(
 96                    set(
 97                        base_name
 98                        for arg in args
 99                        for base_name in arg._get_class_name().split("_")
100                    )))            
101            
102            if class_name in self.created_material_classes:
103                dynamic_class = self.created_material_classes[class_name]
104            else:
105                processed_classes = set()
106                base_densities = self._get_base_densities(args, processed_classes)
107                average_density = sum(base_densities) / len(base_densities)
108
109                dynamic_class = type(
110                    class_name,
111                    (Material,),
112                    {
113                        "density": average_density,
114                    },
115                )
116
117                self.created_material_classes[class_name] = dynamic_class
118                
119            self.used_instances.update(args)
120            total_weight = sum(arg.weight for arg in args)
121            instance = dynamic_class(total_weight)
122            
123            self.current_instances.add(instance)
124            self.all_instances.add(instance)
125            
126            return instance
127        
128    def can_build(self, required_volume):
129        total_volume = sum(
130            instance.volume
131            for instance in self.current_instances
132            if instance not in self.used_instances
133        )
134        return total_volume >= required_volume
135    
136    @classmethod
137    def can_build_together(cls, required_volume):
138        total_volume = sum(
139            instance.volume
140            for instance in cls.all_instances
141            if instance not in cls.used_instances
142        )
143        return total_volume >= required_volume

..........
----------------------------------------------------------------------
Ran 10 tests in 0.014s

OK

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

f1class Material:f1class Material:
2    density = 02    density = 0
3    def __init__(self, weight):3    def __init__(self, weight):
4        self.weight = weight4        self.weight = weight
5    5    
6    @property6    @property
7    def volume(self):7    def volume(self):
8        return self.weight / self.density8        return self.weight / self.density
99
10    def _get_class_name(self):10    def _get_class_name(self):
11        return self.__class__.__name__11        return self.__class__.__name__
1212
1313
14class Concrete(Material):14class Concrete(Material):
15    density = 250015    density = 2500
16    16    
17    17    
18class Brick(Material):18class Brick(Material):
19    density = 200019    density = 2000
2020
2121
22class Stone(Material):22class Stone(Material):
23    density = 160023    density = 1600
2424
2525
26class Wood(Material):26class Wood(Material):
27    density = 60027    density = 600
2828
2929
30class Steel(Material):30class Steel(Material):
31    density = 770031    density = 7700
3232
3333
34class Factory:34class Factory:
35    created_material_classes = {35    created_material_classes = {
36        "Brick": Brick,36        "Brick": Brick,
37        "Concrete": Concrete,37        "Concrete": Concrete,
38        "Steel": Steel,38        "Steel": Steel,
39        "Stone": Stone,39        "Stone": Stone,
40        "Wood": Wood,40        "Wood": Wood,
41    }41    }
42        42        
43    used_instances = set()43    used_instances = set()
44    all_instances = set()44    all_instances = set()
t45    #created_classes = {}t
4645
47    def __init__(self):46    def __init__(self):
48        self.current_instances = set()47        self.current_instances = set()
49    48    
50    def _get_base_densities(self, args, processed_classes):49    def _get_base_densities(self, args, processed_classes):
51        """Get the densities of the base materials used to create the given instances."""50        """Get the densities of the base materials used to create the given instances."""
52        densities = []51        densities = []
5352
54        for arg in args:53        for arg in args:
55            if isinstance(arg, Material):54            if isinstance(arg, Material):
56                class_name = arg._get_class_name()55                class_name = arg._get_class_name()
57                base_classes = class_name.split("_")56                base_classes = class_name.split("_")
5857
59                for base in base_classes:58                for base in base_classes:
60                    if base not in processed_classes:59                    if base not in processed_classes:
61                        if base in self.created_material_classes:60                        if base in self.created_material_classes:
62                            densities.append(self.created_material_classes[base].density)61                            densities.append(self.created_material_classes[base].density)
63                            processed_classes.add(base)62                            processed_classes.add(base)
64                        else:63                        else:
65                            raise ValueError(f"Unknown material base: {base}")64                            raise ValueError(f"Unknown material base: {base}")
66        return densities65        return densities
6766
68    def __call__(self, *args, **kwargs):67    def __call__(self, *args, **kwargs):
69        if not args and not kwargs:68        if not args and not kwargs:
70            raise ValueError("Cannot call with no arguments.")69            raise ValueError("Cannot call with no arguments.")
71        if args and kwargs:70        if args and kwargs:
72            raise ValueError("Cannot mix positional and keyword arguments.")71            raise ValueError("Cannot mix positional and keyword arguments.")
73        72        
74        if kwargs:73        if kwargs:
75            instances = ()74            instances = ()
76            for key, value in kwargs.items():75            for key, value in kwargs.items():
77                if key in self.created_material_classes:76                if key in self.created_material_classes:
78                    material_class = self.created_material_classes[key]77                    material_class = self.created_material_classes[key]
79                    instance = material_class(value)78                    instance = material_class(value)
80                    instances += (instance,)79                    instances += (instance,)
81                    80                    
82                    self.current_instances.add(instance)81                    self.current_instances.add(instance)
83                    self.all_instances.add(instance)82                    self.all_instances.add(instance)
84                else:83                else:
85                    raise ValueError(f"Invalid name of keyword argument: {key}")84                    raise ValueError(f"Invalid name of keyword argument: {key}")
86            return instances85            return instances
87        86        
88        if args:87        if args:
89            for arg in args:88            for arg in args:
90                if arg in self.used_instances:89                if arg in self.used_instances:
91                    raise AssertionError(f"Instance {arg} has already been used.")90                    raise AssertionError(f"Instance {arg} has already been used.")
92                if not any(isinstance(arg, cls) for cls in self.created_material_classes.values()):91                if not any(isinstance(arg, cls) for cls in self.created_material_classes.values()):
93                    raise ValueError(f"Invalid material instance: {arg}")92                    raise ValueError(f"Invalid material instance: {arg}")
94            93            
95            class_name = "_".join(94            class_name = "_".join(
96                sorted(95                sorted(
97                    set(96                    set(
98                        base_name97                        base_name
99                        for arg in args98                        for arg in args
100                        for base_name in arg._get_class_name().split("_")99                        for base_name in arg._get_class_name().split("_")
101                    )))            100                    )))            
102            101            
103            if class_name in self.created_material_classes:102            if class_name in self.created_material_classes:
104                dynamic_class = self.created_material_classes[class_name]103                dynamic_class = self.created_material_classes[class_name]
105            else:104            else:
106                processed_classes = set()105                processed_classes = set()
107                base_densities = self._get_base_densities(args, processed_classes)106                base_densities = self._get_base_densities(args, processed_classes)
108                average_density = sum(base_densities) / len(base_densities)107                average_density = sum(base_densities) / len(base_densities)
109108
110                dynamic_class = type(109                dynamic_class = type(
111                    class_name,110                    class_name,
112                    (Material,),111                    (Material,),
113                    {112                    {
114                        "density": average_density,113                        "density": average_density,
115                    },114                    },
116                )115                )
117116
118                self.created_material_classes[class_name] = dynamic_class117                self.created_material_classes[class_name] = dynamic_class
119                118                
120            self.used_instances.update(args)119            self.used_instances.update(args)
121            total_weight = sum(arg.weight for arg in args)120            total_weight = sum(arg.weight for arg in args)
122            instance = dynamic_class(total_weight)121            instance = dynamic_class(total_weight)
123            122            
124            self.current_instances.add(instance)123            self.current_instances.add(instance)
125            self.all_instances.add(instance)124            self.all_instances.add(instance)
126            125            
127            return instance126            return instance
128        127        
129    def can_build(self, required_volume):128    def can_build(self, required_volume):
130        total_volume = sum(129        total_volume = sum(
131            instance.volume130            instance.volume
132            for instance in self.current_instances131            for instance in self.current_instances
133            if instance not in self.used_instances132            if instance not in self.used_instances
134        )133        )
135        return total_volume >= required_volume134        return total_volume >= required_volume
136    135    
137    @classmethod136    @classmethod
138    def can_build_together(cls, required_volume):137    def can_build_together(cls, required_volume):
139        total_volume = sum(138        total_volume = sum(
140            instance.volume139            instance.volume
141            for instance in cls.all_instances140            for instance in cls.all_instances
142            if instance not in cls.used_instances141            if instance not in cls.used_instances
143        )142        )
144        return total_volume >= required_volume143        return total_volume >= required_volume
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

n1class Concrete:n1class Material:
2    density = 25002    density = 0
3    def __init__(self, weight):
4        self.weight = weight
5    
6    @property
7    def volume(self):
8        return self.weight / self.density
9    
10    
11class Brick:
12    density = 2000
13    def __init__(self, weight):3    def __init__(self, weight):
14        self.weight = weight4        self.weight = weight
15    5    
16    @property6    @property
17    def volume(self):7    def volume(self):
18        return self.weight / self.density8        return self.weight / self.density
199
n20 n10    def _get_class_name(self):
21class Stone:11        return self.__class__.__name__
22    density = 1600
23    def __init__(self, weight):
24        self.weight = weight
25    
26    @property
27    def volume(self):
28        return self.weight / self.density
2912
3013
n31class Wood:n14class Concrete(Material):
32    density = 60015    density = 2500
33    def __init__(self, weight):
34        self.weight = weight
35    16    
n36    @propertyn17    
37    def volume(self):18class Brick(Material):
38        return self.weight / self.density19    density = 2000
3920
4021
n41class Steel:n22class Stone(Material):
23    density = 1600
24 
25 
26class Wood(Material):
27    density = 600
28 
29 
30class Steel(Material):
42    density = 770031    density = 7700
n43    def __init__(self, weight):n
44        self.weight = weight
45 
46    @property
47    def volume(self):
48        return self.weight / self.density
4932
5033
51class Factory:34class Factory:
n52    base_material_classes = {n35    created_material_classes = {
53        "Brick": Brick,36        "Brick": Brick,
54        "Concrete": Concrete,37        "Concrete": Concrete,
55        "Steel": Steel,38        "Steel": Steel,
56        "Stone": Stone,39        "Stone": Stone,
57        "Wood": Wood,40        "Wood": Wood,
58    }41    }
59        42        
60    used_instances = set()43    used_instances = set()
61    all_instances = set()44    all_instances = set()
n62    created_classes = {}n45    #created_classes = {}
6346
64    def __init__(self):47    def __init__(self):
65        self.current_instances = set()48        self.current_instances = set()
66    49    
n67    def _get_base_class_name(self, instance):n
68        """Get the base class name of a material instance."""
69        return instance.__class__.__name__.split("_")
70    
71    def _get_base_densities(self, args, processed_classes):50    def _get_base_densities(self, args, processed_classes):
72        """Get the densities of the base materials used to create the given instances."""51        """Get the densities of the base materials used to create the given instances."""
73        densities = []52        densities = []
nn53 
74        for arg in args:54        for arg in args:
n75            if isinstance(arg, tuple(Factory.base_material_classes.values())):n55            if isinstance(arg, Material):
76                base_name = arg.__class__.__name__
77                if base_name not in processed_classes:
78                    densities.append(arg.density)
79                    processed_classes.add(base_name)
80            elif isinstance(arg.__class__, type):
81                class_name = arg.__class__.__name__56                class_name = arg._get_class_name()
82                base_classes = class_name.split("_")57                base_classes = class_name.split("_")
nn58 
83                for base in base_classes:59                for base in base_classes:
84                    if base not in processed_classes:60                    if base not in processed_classes:
nn61                        if base in self.created_material_classes:
85                        densities.append(Factory.base_material_classes[base].density)62                            densities.append(self.created_material_classes[base].density)
86                        processed_classes.add(base)63                            processed_classes.add(base)
64                        else:
65                            raise ValueError(f"Unknown material base: {base}")
87        return densities66        return densities
8867
89    def __call__(self, *args, **kwargs):68    def __call__(self, *args, **kwargs):
90        if not args and not kwargs:69        if not args and not kwargs:
91            raise ValueError("Cannot call with no arguments.")70            raise ValueError("Cannot call with no arguments.")
92        if args and kwargs:71        if args and kwargs:
93            raise ValueError("Cannot mix positional and keyword arguments.")72            raise ValueError("Cannot mix positional and keyword arguments.")
94        73        
95        if kwargs:74        if kwargs:
96            instances = ()75            instances = ()
97            for key, value in kwargs.items():76            for key, value in kwargs.items():
n98                if key in Factory.base_material_classes:n77                if key in self.created_material_classes:
99                    material_class = Factory.base_material_classes[key]78                    material_class = self.created_material_classes[key]
100                    instance = material_class(value)79                    instance = material_class(value)
101                    instances += (instance,)80                    instances += (instance,)
102                    81                    
103                    self.current_instances.add(instance)82                    self.current_instances.add(instance)
n104                    Factory.all_instances.add(instance)n
105                elif key in self.created_classes:
106                    material_class = Factory.created_classes[key]
107                    instance = material_class(value)
108                    instances += (instance,)
109                    
110                    self.current_instances.add(instance)83                    self.all_instances.add(instance)
111                    Factory.all_instances.add(instance)
112                else:84                else:
113                    raise ValueError(f"Invalid name of keyword argument: {key}")85                    raise ValueError(f"Invalid name of keyword argument: {key}")
114            return instances86            return instances
115        87        
116        if args:88        if args:
117            for arg in args:89            for arg in args:
n118                if arg in Factory.used_instances:n90                if arg in self.used_instances:
119                    raise AssertionError(f"Instance {arg} has already been used.")91                    raise AssertionError(f"Instance {arg} has already been used.")
n120                if not any(isinstance(arg, cls) for cls in Factory.base_material_classes.values()) and \n
121                    not any(isinstance(arg, cls) for cls in Factory.created_classes.values()):92                if not any(isinstance(arg, cls) for cls in self.created_material_classes.values()):
122                    raise ValueError(f"Invalid material instance: {arg}")93                    raise ValueError(f"Invalid material instance: {arg}")
123            94            
n124            class_name = "_".join(sorted(set(name for arg in args for name in self._get_base_class_name(arg))))n95            class_name = "_".join(
96                sorted(
97                    set(
98                        base_name
99                        for arg in args
100                        for base_name in arg._get_class_name().split("_")
101                    )))            
102            
125            if class_name in Factory.created_classes:103            if class_name in self.created_material_classes:
126                dynamic_class = Factory.created_classes[class_name]104                dynamic_class = self.created_material_classes[class_name]
127            else:105            else:
128                processed_classes = set()106                processed_classes = set()
129                base_densities = self._get_base_densities(args, processed_classes)107                base_densities = self._get_base_densities(args, processed_classes)
130                average_density = sum(base_densities) / len(base_densities)108                average_density = sum(base_densities) / len(base_densities)
131109
132                dynamic_class = type(110                dynamic_class = type(
133                    class_name,111                    class_name,
n134                    (object,),n112                    (Material,),
135                    {113                    {
n136                        "__init__": lambda self, weight: setattr(self, "weight", weight),n
137                        "density": average_density,114                        "density": average_density,
n138                        "volume": property(lambda self: self.weight / self.density),n
139                    },115                    },
140                )116                )
141117
n142                Factory.created_classes[class_name] = dynamic_classn118                self.created_material_classes[class_name] = dynamic_class
143                119                
n144            Factory.used_instances.update(args)n120            self.used_instances.update(args)
145            total_weight = sum(arg.weight for arg in args)121            total_weight = sum(arg.weight for arg in args)
146            instance = dynamic_class(total_weight)122            instance = dynamic_class(total_weight)
147            123            
148            self.current_instances.add(instance)124            self.current_instances.add(instance)
n149            Factory.all_instances.add(instance)n125            self.all_instances.add(instance)
150            126            
151            return instance127            return instance
152        128        
153    def can_build(self, required_volume):129    def can_build(self, required_volume):
154        total_volume = sum(130        total_volume = sum(
155            instance.volume131            instance.volume
156            for instance in self.current_instances132            for instance in self.current_instances
t157            if instance not in Factory.used_instancest133            if instance not in self.used_instances
158        )134        )
159        return total_volume >= required_volume135        return total_volume >= required_volume
160    136    
161    @classmethod137    @classmethod
162    def can_build_together(cls, required_volume):138    def can_build_together(cls, required_volume):
163        total_volume = sum(139        total_volume = sum(
164            instance.volume140            instance.volume
165            for instance in cls.all_instances141            for instance in cls.all_instances
166            if instance not in cls.used_instances142            if instance not in cls.used_instances
167        )143        )
168        return total_volume >= required_volume144        return total_volume >= required_volume
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op