Skip to content
Advertisement

Cleaner Alternative to Nested If/Else

I’m mainly focused on an alternative to if/else’s in create_animal. If there is a more professional way to handle this.

In this case, it’s a classifier based on a variable number of traits needed to figure out what the animal is. Since humans are the only animals that speak English, that property is sufficient. But if they roar instead Bear and Lion need an additional property of habitat to figure it out. I know I could group those conditionals more succinctly, but that’s not what I’m trying to illustrate.

class Human:
    self.family = 'Hominidae'
    self.order = 'Primate'

class Bear:
    self.family = 'Ursidae'
    self.order = 'Carnivora'

class Lion:
    self.family = 'Felidae'
    self.order = 'Carnivora'
    
def create_animal(language, roars, habitat):
    if language == 'English':
        return Human()
    elif roars == True:
        if habitat == 'forest':
            return Bear()
        elif habitat == 'savannah':
            return Lion()

animal1 = create_animal(None, roars=True,habitat='forest') # Will be a bear
animal2 = create_animal(language = 'English', roars=False,habitat='town') # Will be a human
animal3 = create_animal(language = None, roars=True,habitat='savannah') # Will be a lion

This will work, but for some real world complexity, I don’t like how nasty the nested if/else’s are getting and I figure there must a good way to do it with a classification map like this, but I’m not sure how to approach it.

species_classification_map = {
    'speaks_english':Human(),
    'roars':{
        'forest':Bear(),
        'savannah':Lion()
    }}

Advertisement

Answer

One option that at least standardizes your function inputs is to have each animal classified by it’s language and habitat and store it in a dictionary

class Human():
    def __init__(self):
        self.family = 'Hominidae'
        self.order = 'Primate'

class Bear():
    def __init__(self):
        self.family = 'Ursidae'
        self.order = 'Carnivora'

class Lion():
    def __init__(self):
        self.family = 'Felidae'
        self.order = 'Carnivora'
    
def create_animal(language, habitat):
    #dict of language, habitat
    animals={('english','civilization'):Human(),
            ('roars','forest'):Bear(),
            ('roars','savannah'):Lion()}
    #human habitat could also be None for simplicity
    return animals[(language,habitat)]

b=create_animal('roars','forest')
b
<__main__.Bear at 0x210c8795460>

some_dude=create_animal('english','civilization')
some_dude
<__main__.Human at 0x210c87953a0>
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement