Search code examples
pythonclassinstances

How can I combine (or make operations) between attributes of different classes (without specifying instances yet)?


First of all, I am a total newbie. Thanks for your patience.

I am designing a piece of software to calculate insulation materials and amounts on different houses.

I have a class House(), which holds attributes like roof_area and wall_area.

I have a class Insulator(), which holds attributes like thickness and area (the area the packaged material covers)

Now I want to know how many packages of the insulator I should buy in order to cover the whole roof area.

So, the operation would be:

House.roof_area / Insulator.area = insulator_packages_needed_for_roof

The thing is I can't do that operation:

AttributeError: type object 'House' has no attribute 'roof_area'. 

Of course I could do it a an instance scope, but I don't want to specify an instance yet, as this operation should be done for any instance of the Class that gets build in the future. Should I use inheritance? My feeling is that, given that Insulator and House are totally different things, they shouldn't be mixed by inheritance, but I am just a beginner.


Solution

  • It doesn't make any sense to try to compute the number of insulation packages you need to cover the roof of a house, without using any instances of your House or Insulator classes. It only makes sense if you have one instance of each.

    You can, however, write the code to do the calculation before you've created the instances. Just put it in a function that takes the instances as arguments:

    def roof_insulation_packages(house, insulator):  # args are instances of House and Insulator
        return house.roof_area / insulator.area  # do the calculation and return it
    

    It might make more sense for the function to be a method of one of the classes. I'd even suggest that Insulator instances might be a good candidates to be instance attributes of the House. That would look something like this:

    class House():
        def __init__(self, roof_area, roof_insulator, wall_area, wall_insulator):
            self.roof_area = roof_area
            self.roof_insulator = roof_insulator
            self.wall_area = wall_area
            self.wall_insulator = wall_insulator
    
        def calculate_roof_insulation_packages(self):
            return self.roof_area / self.roof_insulator.area
    
        def calculate_wall_insulation_packages(self, insulator):
            return self.wall_area / self.wall_insulator.area
    

    You'd create the house instance with something like this (I'm making up the arguments to the Insulator class, so don't pay too much attention to that part):

    good_roof_insulation = Insulator(4, 5) # nonsense args
    cheap_wall_insulation = Insulator(5, 12)
    
    my_house = House(100, good_roof_insulation, 87, cheap_wall_insulation)