Home > other >  Clean way to assign conditional dict values without repeating dict
Clean way to assign conditional dict values without repeating dict

Time:07-03

I'm working on my python and design pattern skills trying to model a game out.

A character can have a hierarchical rank so wanted to use an Enum to specify ranks like:

class Ranks(Enum):
   BEGINNER = 0
   MID = 1
   ADVANCED = 2

Based on that rank a different set of starting abilities is assigned, so I wanted to add a property to the enum class:

class Ranks(Enum):
   BEGINNER = 0
   MID = 1
   ADVANCED = 2

   @property
   def raw_abilities(self):
      abilities = {}
      if self.value == 0:
         abilities = {
            'will': 1,
            'health': 1
         }
      elif self.value == 1:
         ....etc

      return abilities

   @property
   def special_abilities(self):
      abilities = {}
      if self.value == 0:
         abilities = {
            'resources': 1,
            'circles': 1
         }
      elif self.value == 1:
         ....etc

      return abilities

This repetitive n * ranks code doesn't seem very elegant. Is there a better way to describe that.

Considerations:

  • other abilities/skills will be added later. This enum class simply carries a starting point for a Character class.

CodePudding user response:

You can use:

from enum import Enum


class Ranks(Enum):
    BEGINNER = (0, {'will': 1, 'health': 1})
    MID = (1, {'will': 2, 'health': 2})
    ADVANCED = (2, {'will': 3, 'health': 3})

    def __init__(self, v1, v2):
        self.v1 = v1
        self.v2 = v2

    @property
    def raw_abilities(self):
        return self.v2

https://docs.python.org/3/library/enum.html#planet

CodePudding user response:

I think a simple answer in this case is to mainatain a map of rank -> abilities (dictionary), like so:

rank_to_abilities = {
    BEGINNER: {
            'will': 1,
            'health': 1
         },
    MID: {
            'will': 2,
            'health': 2
         }
    ADVANCED: {
            'will': 3,
            'health': 3
         }
}

Then you can simply do:

@property
def raw_abilities(self):
    return rank_to_abilities[self.rank]

Encapsulated within the enum (I wouldn't do this):

class Ranks(Enum):
   BEGINNER = 0
   MID = 1
   ADVANCED = 2
   
   @property
   def abilites(self):
        return {
            Ranks.BEGINNER.value: {
                    'will': 1,
                    'health': 1
                 },
            Ranks.MID.value: {
                    'will': 2,
                    'health': 2
                 },
            Ranks.ADVANCED.value: {
                    'will': 3,
                    'health': 3
                 }
            }[self.value]
  • Related