Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Can't call child class method from parent class

I was wondering if someone can tell me the error. Why I can’t access the child class method from the parent class. Thank you!

Code is about a game where we have a soldier and his inventory. I try to call Soldier().add_weapon but it returns an error that no add_weapon exists for Soldier

Code:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

class Soldier():
    def __init__(self, name, price, health=100, kills=0, type='human'):

        assert price >= 0 
        assert health >= 0 
        assert kills >= 0
        assert type is 'human' or 'air' or 'ground'
        #assert inventory 

        self.name = name
        self.price = price
        self.health = health
        self.kills = kills
        self.type = type

    @property
    def get_name(self):
        return self._name

    @get_name.setter
    def set_name(self, value):
        self._name = value

    def get_health(self):
        return self.health

    def set_health(self, value):
        self.health = value

    def face_damage(self, value):
        self.health = self.health - int(value)

    def is_alive(self):
        if self.health > 0:
            return True
        else:
            return False

    def get_inventory(self):
        pass

class Inventory(Soldier):

    def __init__(self):

        super().__init__(
            
        )
    
        self.inv = []
    
    def add_weapon(self, item):
        
        if item not in self.inv:

            self.inv.append(item)
        
        else: None

    def get_total_attack(self, weapon_specs = {
     'rifle': {'air': 1, 'ground': 2, 'human': 5},
     'pistol': {'air': 0, 'ground': 1, 'human': 3},
     'rpg': {'air': 5, 'ground': 5, 'human': 3},
     'warhead': {'air': 10, 'ground': 10, 'human': 10},
     'machine gun': {'air': 3, 'ground': 3, 'human': 10}
     }):
     
        damages = {}
        for weapon in self.inv:
            for k,v in weapon_specs[weapon].items():
                damages[k] = damages.get(k, 0) + v
        
        return damages

    '''
    def get_inventory(self):
        for x in self.inv:
            return x
    '''

    def attack(self, value, total):
        for i in self.inv:
            for k in total:
                return total[k]
        


def test_p2_4():
  soldier = Soldier('ranger', 100)
  soldier.add_weapon('rifle')
  soldier.add_weapon('machine gun')
  soldier.add_weapon('rpg')
  inventory = soldier.get_inventory()
  damages = inventory.get_total_attack()
  correct = damages['air'] == 9 and damages['ground'] == 10 and damages['human'] == 18
  assert correct
  return "Passed!"


print(test_p2_4())

Error I get
:

AttributeError: ‘Soldier’ object has no attribute ‘add_weapon’

>Solution :

The way you’ve written your code, an Inventory is a type of Soldier, which doesn’t make sense. Instead, a Soldier should have an Inventory:

class Soldier:
    def __init__(self, name, price, health=100, kills=0, soldier_type='human'):

        assert price >= 0
        assert health >= 0
        assert kills >= 0
        assert soldier_type in ('human', 'air', 'ground')
        self.name = name
        self.price = price
        self.health = health
        self.kills = kills
        self.type = soldier_type
        self.inventory = Inventory()

    @property
    def get_name(self):
        return self._name

    @get_name.setter
    def set_name(self, value):
        self._name = value

    def get_health(self):
        return self.health

    def set_health(self, value):
        self.health = value

    def face_damage(self, value):
        self.health = self.health - int(value)

    def is_alive(self):
        if self.health > 0:
            return True
        else:
            return False

    def get_inventory(self):
        return self.inventory


class Inventory:

    weapon_specs = {
        'rifle': {'air': 1, 'ground': 2, 'human': 5},
        'pistol': {'air': 0, 'ground': 1, 'human': 3},
        'rpg': {'air': 5, 'ground': 5, 'human': 3},
        'warhead': {'air': 10, 'ground': 10, 'human': 10},
        'machine gun': {'air': 3, 'ground': 3, 'human': 10}
    }

    def __init__(self):
        self.inv = set()

    def add_weapon(self, item):
        # No need to dedupe since we made this a set instead of a list.
        self.inv.add(item)

    def get_total_attack(self):
        damages = {}
        for weapon in self.inv:
            for k, v in self.weapon_specs[weapon].items():
                damages[k] = damages.get(k, 0) + v
        return damages

    def get_inventory(self):
        return self.inv

    def attack(self, total):
        # not sure what this is actually supposed to do, but this
        # is the closest approximation of what your code was TRYING to do?
        return total.values()


def test_p2_4():
    soldier = Soldier('ranger', 100)
    inventory = soldier.get_inventory()
    inventory.add_weapon('rifle')
    inventory.add_weapon('machine gun')
    inventory.add_weapon('rpg')
    damages = inventory.get_total_attack()
    assert damages['air'] == 9 and damages['ground'] == 10 and damages['human'] == 18
    return "Passed!"


print(test_p2_4())
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading