1

I am defining models for my app and I need to a column named 'status' for various verification procedures. Here is a simplified user model.

class User
    id(int)
    name(str)
    status(int) # 0- New 1-Active 2-Inactive 3-Reported 4-Deleted

I asked a fellow Python developer to review my code; and he suggested that I avoided 'magic numbers'. His solution is this:

class Choices:
    @classmethod
    def get_value(cls, key):
        # get the string display if need to show
        for k, v in cls.CHOICES:
            if k == key:
                return v
        return ""

class UserStatusChoices(Choices):
    NEW = 0
    ACTIVE = 1
    INACTIVE = 2
    REPORTED = 3
    DELETED = 4

    CHOICES = (
        (NEW, "NEW"),
        (ACTIVE, "ACTIVE"),
        (INACTIVE, "INACTIVE"),
        (REPORTED, "REPORTED"),
        (DELETED, "DELETED"),
    )

Couldn't I use simple dictionaries instead? Does anyone see a good reason for 'class'y solution?

Dogukan Tufekci
  • 2,978
  • 3
  • 17
  • 21
  • 1
    How about this one http://stackoverflow.com/a/4472993/1481060 – sotapme Feb 28 '13 at 09:54
  • I use things like this quite often. I've thought about http://docs.python.org/2/library/collections.html#collections.namedtuple though. I think it's a better idea than a dict as you're not typing strings – YXD Feb 28 '13 at 10:04
  • I am a beginner level programmer so easier solutions makes more sense. It seems like if I want to use one way number picking, then dictionary is good enough. However, if the program demands the second opposite direction int to string function, then it would be a better choice to go with a class'y foundation. – Dogukan Tufekci Feb 28 '13 at 10:21

1 Answers1

3

Building on Python Enum class (with tostring fromstring)

class Enum(object):
    @classmethod
    def tostring(cls, val):
        for k,v in vars(cls).iteritems():
            if v==val:
                return k

    @classmethod
    def fromstring(cls, str):
        return getattr(cls, str.upper(), None)

    @classmethod
    def build(cls, str):
        for val, name in enumerate(str.split()):
            setattr(cls, name, val)
class MyEnum(Enum):
    VAL1, VAL2, VAL3 = range(3)

class YourEnum(Enum):
    CAR, BOAT, TRUCK = range(3)

class MoreEnum(Enum):
    pass

print MyEnum.fromstring('Val1')
print MyEnum.tostring(2)
print MyEnum.VAL1 

print YourEnum.BOAT
print YourEnum.fromstring('TRUCK')

# Dodgy semantics for creating enums.
# Should really be
# MoreEnum = Enum.build("CIRCLE SQUARE")
MoreEnum.build("CIRCLE SQUARE")
print MoreEnum.CIRCLE
print MoreEnum.tostring(1)
print MoreEnum.tostring(MoreEnum.CIRCLE)

EDIT Added build class method so that a string could be used to build the enums.

Although there are probably better solutions out there.

Community
  • 1
  • 1
sotapme
  • 4,695
  • 2
  • 19
  • 20