My solution to the Codecademy Pro Project “Become A Pokemon Master!”. Create a Pokemon Class and a Trainer Class in Python, adding functionality to include healing, battle damage, level ups and evolves! Note – lovers of the official characters will probably be horrified to learn I’ve just assigned the Pokemon random stats. This is just for fun!

class Pokemon:
  def __init__(self, name='Default', level=1, element='Grass', maxhealth=100, curr_health=10, concious=True, attack=1, defence=1, speed=1):
    self.name = name
    self.level = level
    self.element = element
    self.maxhealth = maxhealth
    self.curr_health = curr_health
    self.concious = concious
    self.attack = attack
    self.defence = defence
    self.speed = speed
    self.experience = 0
    #establishes advantages for the pokemon on instantiation
    if self.element == 'Fire':
      self.disadvantage = 'Water'
      self.advantage = 'Grass'
    elif self.element == 'Water':
      self.disadvantage = 'Grass'
      self.advantage = 'Fire'
    else:
      self.advantage = 'Water'
      self.disadvantage = 'Fire'

  def __repr__(self):
    return 'Pokemon Object {}'.format(self.name)

  #method for displaying pokemon status
  def status(self):
    print('Current stats for {}:\n'.format(self.name))
    print('Level: {}'.format(self.level))
    print('Element: {}'.format(self.element))
    print('Max Health: {}'.format(self.maxhealth))
    print('Current Health: {}'.format(self.curr_health))
    print('ATK: {}  DEF: {} SPEED: {}'.format(self.attack, self.defence, self.speed))
    print('XP: {}'.format(self.experience))
    if not self.concious:
      print('Awareness: Unconcious')
    else:
      print('Awareness: Concious')
    print('Has advantage over {} Pokemon.'.format(self.advantage))
    print('Has disadvantage against {} Pokemon.\n'.format(self.disadvantage))

  #method to render pokemon unconcious
  def ko(self):
    if not self.concious:
      print('{} is already unconcious!\n'.format(self.name))
    else:
      print('{} is rendered unconcious!\n'.format(self.name))
      self.concious = False
      self.curr_health = 0

  #method to revive pokemon from unconciousness
  def revive(self):
    if self.concious:
      print('{} is already concious!\n'.format(self.name))
    else:
      print('{} is revived!\n'.format(self.name))
      self.concious = True

  #method to calculate the effects of damage
  def damage(self, damage):
    if damage >= self.curr_health:
      print('{} takes {} damage!\n'.format(self.name, damage))
      self.ko()
    else:
      self.curr_health -= damage
      print('{} takes {} damage and has {} health remaining.\n'.format(self.name, damage, self.curr_health))

  #method to calculate the effects of healing
  def heal(self, heal):
    if self.curr_health + heal >= self.maxhealth:
      print('{} is healed to max health!\n'.format(self.name))
      self.curr_health = self.maxhealth
    else:
      self.curr_health += heal
      print('{} is healed for {} hit points and now has {} remaining.\n'.format(self.name, heal, self.curr_health))
    if not self.concious:
      self.revive()

  #method to calculate the effects of battle, according to advantages
  def defend(self, pokemon):
    print('{} is attacked by {}!'.format(self.name, pokemon.name))
    #implement benefits provided by stats
    damage = (pokemon.level + pokemon.attack)
    if self.disadvantage == pokemon.element:
      self.damage((damage * 2) - self.defence)
    elif self.advantage == pokemon.element:
      self.damage(round(damage / 2) - self.defence)
    else:
      self.damage(damage - self.defence)

  #method to handle experience gain and manage levels
  def addxp(self, xp):
    self.experience += xp
    #checks for level up and retains excess experience
    if self.experience >= 500:
      self.experience -= 500
      self.level += 1
      print('{} has levelled up and is now level {}!\n'.format(self.name, self.level))
   #evolves every 5 levels
      if self.level % 5 == 0:
        self.evolve()

  def evolve(self):
    print('{} has evolved, +1 added to all stats!'.format(self.name))
    self.attack += 1; self.defence += 1; self.speed += 1

class Trainer:
  def __init__(self, name='Default', pokemons=None, potions=0, active=1):
    self.name = name
    self.potions = potions
    if pokemons is None:
      self.pokemons = []
      self.active = None
    else:
      self.pokemons = pokemons
      self.active = self.pokemons[active - 1]
    #cuts list if more than 6 pokemon in list
    while len(self.pokemons) > 6:
      print('Too many Pokemon! {} is cut from {}\'s roster.\n'.format((self.pokemons.pop()).name, self.name))

  def __repr__(self):
    print('Pokemon Trainer Object {}'.format(self.name))
  
  #display trainer status
  def status(self):
    print('Current stats for {}:\n'.format(self.name))
    print('Potions Remaining: {}'.format(self.potions))
    if self.pokemons:
      print('Active Pokemon: {}\n'.format((self.active).name))
      self.listpokemon()
    else:
      print('No Pokemon to make active.\n')
    
  #list available pokemon
  def listpokemon(self):
    print('{} has collected the following Pokemon:\n'.format(self.name))
    for i in range(len(self.pokemons)):
      print('{}: {}'.format(i + 1, (self.pokemons[i]).name))
    print('')

  #function to change the current active Pokemon
  def make_active(self, activate):
    try:
      if not (self.pokemons[activate - 1]).concious:
        print('{n} is unconcious, you can\'t activate {n}.\n'.format(n=(self.pokemons[activate -1 ]).name))
      else:
        self.active = self.pokemons[activate - 1]
        print('{}\'s active Pokemon is now {}.\n'.format(self.name, (self.active).name))
    except:
      print('Invalid Pokemon selected. Try listing your Pokemon.\n')

  #calculate effects of trainer using a healing potion
  def usepotion(self):
    if (self.active).curr_health == (self.active).maxhealth:
      print('{} is already at max health!\n'.format(self.name))
    elif self.potions > 0:
      print('{} uses a potion to heal {} for 25 hit points!\n'.format(self.name, (self.active.name)))
      #call the pokemon heal method
      (self.active).heal(25)
      self.potions -= 1
    else:
      print('{} doesn\'t have enough potions to do that!\n'.format(self.name))

  def pokemonstatus(self):
    if self.active is None:
      print('{} does not have an active Pokemon.'.format(self.name))
    else:
      (self.active).status()

  #calculate effects of trainer attacking with active pokemon
  def attack(self, trainer):
    if self.active is None:
      print('{} cannot attack without an active Pokemon!'.format(self.name))
    elif not (self.active).concious:
      print('{} cannot attack with an unconcious Pokemon!\n'.format(self.name))
    elif not (trainer.active).concious:
      print('{} automatically wins, but gains no XP as {}\'s Pokemon is unconcious.\n'.format(self.name, trainer.name))
    else:
      print('{} attacks {}!\n'.format(self.name, trainer.name))
      (trainer.active).defend(self.active)
      if not (trainer.active).concious:
        print('{} renders {} unconcious, winning the battle and gaining 100 XP!\n'.format((self.active).name, (trainer.active).name))
        (self.active).addxp(100)

def autobattle (trainer1, trainer2):
  #implement effects of speed stat
  if (trainer2.active).speed > (trainer1.active).speed:
    gonext = True
    print('{} has the faster active Pokemon and attacks first!\n'.format(trainer2.name))
  else:
    gonext = False
    print('{} has the faster active Pokemon and attacks first!\n'.format(trainer1.name))
  if not (trainer1.active).concious:
    print('Cannot auto-battle, {}\'s Pokemon is unconcious.'.format(trainer1.name))
    return
  if not (trainer2.active).concious:
    print('Cannot auto-battle, {}\'s Pokemon is unconcious.'.format(trainer2.name))
    return
  while (trainer1.active).concious and (trainer2.active).concious:
    if gonext:
      trainer2.attack(trainer1)
      gonext = False
    else:
      trainer1.attack(trainer2)
      gonext = True
  return

#test data

bob_pickachu = Pokemon('Pickachu', 3, 'Fire', 100, 0, False, 2, 2, 2)
bob_charmander = Pokemon('Charmander', 5, 'Water', 100, 50, True, 1, 2, 3)
bob_grassgalor = Pokemon('Grassgalor', 8, 'Grass', 100, 24, True, 3, 1, 2)
jane_pickachu = Pokemon('Pickachu', 4, 'Fire', 100, 80, True, 2, 2, 2)
jane_charmander = Pokemon('Charmander', 3, 'Water', 100, 30, True, 1, 2, 3)
jane_grassgalor = Pokemon('Grassgalor', 5, 'Grass', 100, 50, True, 3, 1, 2)
jim_grassgalor = Pokemon('Grassgalor', 10, 'Grass', 100, 100, True, 3, 1, 2)
bobs_mons = [bob_pickachu, bob_charmander, bob_grassgalor]
janes_mons = [jane_pickachu, jane_charmander, jane_grassgalor]
jims_mons = [jane_pickachu, jane_charmander, jane_grassgalor, bob_pickachu, bob_charmander, bob_grassgalor, jim_grassgalor]
bob = Trainer('Bob', bobs_mons, 3, 1)
jane = Trainer('Jane', janes_mons, 3, 1)
jim = Trainer('Jim', jims_mons, potions=3, active=1)