I have been programming with Python on-and-off for about 2 years now, even now I still find that when I look at other applications I struggle to follow along with their classes/objects. Please help me improve upon my own OOP experience.
Here is one of my more recent projects for a Django Website.
pokemon.py
# pylint: disable=too-many-instance-attributes,too-many-locals,too-many-branches,too-many-statements
""" Represent Pokemon objects """
from pokedex.models import Pokemon as pokemon, PokemonTypes, PokemonStats, PokemonAbilities, \
PokemonSpecies, PokemonGenderRatios, PokemonProse, PokemonMoves, Types
class PokemonList:
"""
A Class to represent all Pokemon
"""
def __init__(self, page):
"""
Gets 100 pokemon at a time based off of the GET variable "page"
:param page: Defaults to 1. Is used for pagination
"""
self.poke_list = []
if page == 1:
all_rows = [list(x) for x in list(
pokemon.objects.filter(id__range=(0, 100)).values_list(
'id', 'identifier', 'height', 'weight'))]
else:
OFFSET = int(page) * 100
all_rows = [list(x) for x in list(
pokemon.objects.filter(id__range=(OFFSET - 99, OFFSET)).values_list(
'id', 'identifier', 'height', 'weight'))]
for row in all_rows:
type_list = list(Types.objects.filter(
pokemontypes_type__pokemon__id=row[0]).values_list('identifier', flat=True))
row.append(type_list)
self.poke_list.append(row)
class Pokemon:
"""
A Class to represent a pokemon.
"""
def __init__(self, poke_id):
"""
Instantiate a pokemon object with base information
:param poke_id: id of the pokemon to get from the database
"""
# Select base information about a pokemon
poke = pokemon.objects.get(id=poke_id)
self.id = poke.id
self.static_path = 'pokedex/img/profiles/' + str(self.id) + '.png'
self.long_id = str(self.id).zfill(3)
self.identifier = poke.identifier
self.species_id = poke.species.identifier
self.height = poke.height / 10.0
self.weight = poke.weight / 10.0
self.base_experience = poke.base_experience
self.evolution_chain = self._get_evolution_chain()
self.type = []
self.available_types = ['normal', 'fire', 'water', 'electric', 'grass', 'ice', 'fighting',
'poison', 'ground', 'flying', 'psychic', 'bug', 'rock', 'ghost',
'dragon', 'dark', 'steel', 'fairy']
self.type_static = []
# Get Type (may be multiple)
types = PokemonTypes.objects.filter(pokemon=self.id).select_related('type').values_list(
'type__identifier', flat=True)
for t in types:
self.type.append(t)
self.type_static.append('pokedex/img/types' + t + '-type.png')
# Get base stats
stat = [list(x) for x in list(
PokemonStats.objects.filter(pokemon=self.id).select_related('stat').values_list(
'stat__identifier', 'base_stat'))]
self.stats = []
for s in stat:
tempdict = {
s[0]: s[1]
}
self.stats.append(tempdict)
# Get Abilities
ability = PokemonAbilities.objects.filter(
pokemon=self.id).select_related('ability').values_list(
'ability__identifier', flat=True)
self.abilities = []
for item in ability:
self.abilities.append(item)
# Get Moves
self.moves = _get_moves()
# Get Gender Rates
gender_obj = PokemonGenderRatios.objects.select_related('ratio').get(pokemon=self.id)
if gender_obj is not None:
self.percent_male, self.percent_female = gender_obj.ratio.percent_male, \
gender_obj.ratio.percent_female
# Get Description if applicable
try:
desc_obj = PokemonProse.objects.get(pokemon=self.id)
self.description = desc_obj.description
except PokemonProse.DoesNotExist:
pass
def prev_pokedex(self):
"""
Returns a dictionary of information about the previous pokemon in pokedex
(path to image, id, and identifier)
"""
prev_id = self.id - 1
if prev_id > 721 or prev_id < 1:
return None
path_to_image = '/pokedex/img/profiles/' + str(prev_id) + '-small.png'
identifier = pokemon.objects.values_list('identifier', flat=True).get(id=prev_id)
prev_pokemon = {
'image': path_to_image,
'id': prev_id,
'identifier': identifier
}
return prev_pokemon
def next_pokedex(self):
"""
Returns a dictionary of information about the next pokemon in pokedex
(path to image, id, and identifier)
"""
next_id = self.id + 1
if next_id > 721 or next_id < 1:
return None
path_to_image = '/pokedex/img/profiles/' + str(next_id) + '-small.png'
identifier = pokemon.objects.values_list('identifier', flat=True).get(id=next_id)
next_pokemon = {
'image': path_to_image,
'id': next_id,
'identifier': identifier
}
return next_pokemon
def _get_evolution_chain(self):
""" Queries for Pokemon Evolution Chain """
# Gather Evolution Chain
evolution_chain = {
'id': self.id,
'identifier': self.identifier
}
# Get previous evolution
try:
evolves_from = PokemonSpecies.objects.get(id=self.id)
except PokemonSpecies.DoesNotExist:
evolves_from = None
if evolves_from is not None and evolves_from.evolves_from_species_id is not None:
evolution = {'id': evolves_from.evolves_from_species_id}
evolution['identifier'] = pokemon.objects.get(id=evolution['id']).identifier
evolution_chain.insert(0, evolution)
try:
prev_evolv = PokemonSpecies.objects.get(id=evolution['id'])
except PokemonSpecies.DoesNotExist:
prev_evolv = None
if prev_evolv is not None and prev_evolv.evolves_from_species_id is not None:
evolution = {'id': prev_evolv.evolves_from_species_id}
evolution['identifier'] = pokemon.objects.get(id=evolution['id']).identifier
evolution_chain.insert(0, evolution)
# Get Next Evolution
try:
next_evol = PokemonSpecies.objects.get(evolves_from_species_id=self.id)
except PokemonSpecies.DoesNotExist:
next_evol = None
if next_evol is not None and next_evol.id is not None:
evolution = {'id': next_evol.id}
evolution['identifier'] = pokemon.objects.get(id=evolution['id']).identifier
evolution_chain.append(evolution)
try:
next_evol = PokemonSpecies.objects.get(evolves_from_species_id=evolution['id'])
except PokemonSpecies.DoesNotExist:
next_evol = None
if next_evol is not None and next_evol.id is not None:
evolution = {'id': next_evol.id}
evolution['identifier'] = pokemon.objects.get(id=evolution['id']).identifier
evolution_chain.append(evolution)
return evolution_chain
def _get_moves(self):
""" Get available moves """
moves = [list(x) for x in list(
PokemonMoves.objects.filter(pokemon=self.id).select_related(
'move__type', 'move').values_list(
'move__identifier',
'move__type__identifier',
'move__power',
'move__pp',
'move__accuracy'))]
moves_list = []
move_ids = []
for move in moves:
if move[0] not in move_ids:
temp_list = [move[0], move[1], move[2], move[3], move[4]]
moves_list.append(temp_list)
move_ids.append(move[0])
return moves_list
def __str__(self):
""" Returns Identifier when str() is called"""
return self.identifier
pokedex
module you are using? Is it something you wrote or some well known Pokemon library? \$\endgroup\$models.py
. I'm in the process of guessing how they are defined, and I (along with others) may have suggestions. \$\endgroup\$