Pokemon Master List Sorting by name

Hello! I am working on the Pokemon Master Project and I have written a “Trainer Class” method that will add a “Pokemon Class” object to a list. I am trying to then get that same method to sort the list by the name of the pokemon. Any suggestions?

Code is below. Thank you!

class Pokemon:

    damage_adjustments = {

        "Fire": {"Fire": .5, "Water": .5, "Grass": 2, "Ice": 2, "Ground": 1, "Flying": 1},
        "Water": {"Fire": 2, "Water": .5, "Grass": .5, "Ice": 1, "Ground": 2, "Flying": 1},    
        "Grass": {"Fire": .5, "Water": 2, "Grass": 2, "Ice": 1, "Ground": 2, "Flying": .5},
        "Ice": {"Fire": .5, "Water": .5, "Grass": 2, "Ice": .5, "Ground": 2, "Flying": 2},
        "Ground": {"Fire": 2, "Water": 1, "Grass": .5, "Ice": 1, "Ground": 1, "Flying": 0},
        "Flying": {"Fire": 1, "Water": 1, "Grass": 2, "Ice": 1, "Ground": 1, "Flying": 1}

    }

    def __init__(self, name, level, type, max_health, current_health, knocked_out=False):
        self.name = name
        self.level = level
        self.type = type
        self.max_health = max_health
        self.current_health = current_health
        self.knocked_out = knocked_out

    def __repr__(self):
        if self.knocked_out == False:
            status = "Ready for Battle!"
        else:
            status = "Knocked Out!"
        return """
    Name - {name}
    Level - {level}
    Type - {type}
    Health - {current_health}/{max_health}
    Current Status - {status}        
        """.format(name = self.name, level = self.level, type = self.type, current_health = self.current_health, max_health = self.max_health, status = status)


    def lose_health(self, damage):
        self.current_health -= damage
        if self.current_health < 0:
            self.current_health = 0
        print("{name}'s health has been reduced by {damage} to {current_health} HP.".format(name=self.name, damage=damage, current_health=self.current_health))
        if self.current_health == 0:
            self.knock_out()
        else:
            print()

    def gain_health(self, health):
        self.current_health += (health)
        if self.current_health > self.max_health:
            self.current_health = self.max_health
        print("{name}'s health has been increased by {health} to {current_health} HP.".format(name=self.name, health=health, current_health=self.current_health))

    def knock_out(self):
        if self.knocked_out == True:
            print("{name} is already knocked out!\n".format(name=self.name))
        else:
            self.knocked_out = True
            print("{name} has been knocked out!\n".format(name = self.name)) 

    def wake_up(self):
        if self.knocked_out == False:
            print("{name} is already awake!\n".format(name=self.name))
        else: 
            self.knocked_out = False
            print("{name} has been woken up!\n".format(name = self.name))

    def attack(self, enemy):
        if self.knocked_out == True:
            print("{name} is currently knocked out and cannot attack.\n".format(name=self.name))
        elif enemy.knocked_out == True:
            print("{name} is currently knocked out and cannot be attacked.\n".format(name=enemy.name))
        else:
            base_attack = self.level * 2
            attack_adjust = self.damage_adjustments[self.type][enemy.type]
            attack_power = base_attack * attack_adjust        
            print("{name} has attacked {enemy} for {attack_power} damage!".format(name=self.name, enemy=enemy.name, attack_power=attack_power))
            enemy.lose_health(attack_power)
            print()

class Trainer:

    def __init__(self, name):
        self.name = name
        self.potions = 10
        self.max_potions = 10
        self.pokemon_managed = []
        self.active_pokemon = 0

    def __repr__(self):
        pokemon_string = ""
        active_pokemon_string = ""

        if not self.pokemon_managed:
            pokemon_string = "None"
            active_pokemon_string = "None"
        else:
            for pokemon in self.pokemon_managed:
                if pokemon == self.pokemon_managed[-1]:
                    pokemon_string += pokemon.name
                else:
                    pokemon_string += (pokemon.name + ", ")
            active_pokemon_string = self.pokemon_managed[self.active_pokemon].name        

        return """
    Name - {name}
    Potions - {potions}/{max_potions}
    Pokemon - {all_pokemon}
    Active Pokemon - {active_pokemon}
        """.format(name=self.name, potions=self.potions, max_potions=self.max_potions, all_pokemon=pokemon_string, active_pokemon=active_pokemon_string)

    def add_pokemon(self, pokemon):
        if pokemon in self.pokemon_managed:
            print("{pokemon_name} is already on {name}'s team.\n".format(pokemon_name=pokemon.name, name=self.name))
        
        else:
            self.pokemon_managed.append(pokemon)
            # Below is where I would like to sort the trainers pokemon list
            #self.pokemon_managed.sort()
            print("{name} has added {pokemon_name} to their team!\n".format(name=self.name, pokemon_name=pokemon.name))

    def remove_pokemon(self, pokemon):
        if pokemon in self.pokemon_managed:
            self.pokemon_managed.remove(pokemon)
            print("{name} has removed {pokemon_name} from their team.\n".format(name=self.name, pokemon_name=pokemon.name))
        else:
            print("{pokemon_name} is not currently on {name}'s team.\n".format(pokemon_name=pokemon.name, name=self.name))
    
    def use_potion(self):
        if self.pokemon_managed[self.active_pokemon].current_health == self.pokemon_managed[self.active_pokemon].max_health:
            print("{pokemon_name} is already at full health.\n".format(pokemon_name=self.pokemon_managed[self.active_pokemon].name))
        elif self.potions == 0:
            print("{name} has no potions left!\n".format(name=self.name))
        elif self.potions > 0:
            self.potions -= 1
            self.pokemon_managed[self.active_pokemon].gain_health(10)

    def change_active_pokemon(self, pokemon):
        if pokemon in self.pokemon_managed:
            self.active_pokemon = self.pokemon_managed.index(pokemon)
            print("{name} has changed his active pokemon to {pokemon_name}.\n".format(name=self.name, pokemon_name=pokemon.name))
        else:
            print("{pokemon_name} is not currently being managed by {name}.\n".format(pokemon_name=pokemon.name, name=self.name))   
1 Like

A bit of a roundabout answer but I’m hoping you hunt down a bit of this yourself. If you already have a list of instances of Pokemon then perhaps just sorting in place is easiest. There’s a method for that and it even takes a specific key parameter to sort by. Perhaps you’ll find operator.attrgetter to be useful?

You can find some details on sorting at the following link-
https://docs.python.org/3/howto/sorting.html#sortinghowto

1 Like

Thank you for the help! I played around with it a little and found the following code to work:

def add_pokemon(self, pokemon):
        if pokemon in self.pokemon_managed:
            print("{pokemon_name} is already on {name}'s team.\n".format(pokemon_name=pokemon.name, name=self.name))
        
        else:
            self.pokemon_managed.append(pokemon)
            self.pokemon_managed.sort(key=attrgetter("name"))
            print("{name} has added {pokemon_name} to their team!\n".format(name=self.name, pokemon_name=pokemon.name))

I am having a little difficulty why using “name” allows it to sort by name though as opposed to using self.name. Also, why does using “potions” not allow me to sort by the number of potions each pokemon has?

1 Like

As soon as I hit it, I realized that potions are a variable for the Trainer class, not the Pokemon class! I tried it with another Pokemon class variables and it worked exactly the same.

1 Like