Home Why use Enums instead simple primitive types
Post
Cancel

Why use Enums instead simple primitive types

Some data value use a basic type like str or int, but not all str and int are valid values of that data value. Enums can limit the possibilities to only a defined set of values.

Example:

Blood type is a string, but have a set of only 8 valid strings. Don’t exist a blood called 'randombloodtype' but 'AB-' is valid.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from enum import Enum

class BloodType(str, Enum):
    A_negative = "A-"
    B_negative = "B-"
    AB_negative = "AB-"
    O_negative = "O-"
    A_positive = "A+"
    B_positive = "B+"
    AB_positive = "AB+"
    O_positive = "O+"

assert "A-" in list(BloodType)
assert "O+" == BloodType.O_positive

So why not just use list?

The below code do the same as the above:

1
2
3
4
5
6
7
8
9
10
11
12
BLOOD_TYPE = [
    "A-",
    "B-",
    "AB-",
    "O-",
    "A+",
    "B+",
    "AB+",
    "O+",
]

assert "A-" in BLOOD_TYPE

But let us suppose we should make a new piece of code. Given the donor blood type, returns the list of allowed recipients.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from typing import List

def blood_type_can_donate_to(donor: str) -> List[str]:
    _recipients = {
        "A-": ["A-", "AB-", "A+", "AB+"],
        "B-": ["B-", "AB-", "B+", "AB+"],
        "AB-": ["AB-", "AB+"],
        "O-": ["A-","B-", "AB-", "O-", "A+", "B+", "AB+", "0+"],
        "A+": ["A+", "AB+"],
        "B+": ["B+", "AB+"],
        "AB+": ["AB+"],
        "O+": ["A+", "B+", "AB+", "O+"]
    }
    return _recipients[donor]

And using enum:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
from enum import Enum
from typing import List

class BloodType(str, Enum):
    A_negative = "A-"
    B_negative = "B-"
    AB_negative = "AB-"
    O_negative = "O-"
    A_positive = "A+"
    B_positive = "B+"
    AB_positive = "AB+"
    O_positive = "O+"

def blood_type_can_donate_to(donor: BloodType) -> List[BloodType]:
    if donor == BloodType.A_negative:
        return [
            BloodType.A_negative,
            BloodType.AB_negative,
            BloodType.A_positive,
            BloodType.AB_positive
        ]
    elif donor == BloodType.B_negative:
        return [
            BloodType.B_negative,
            BloodType.AB_negative,
            BloodType.B_positive,
            BloodType.AB_positive
        ]
    elif donor == BloodType.AB_negative:
        return [
            BloodType.AB_negative,
            BloodType.AB_positive
        ]
    elif donor == BloodType.O_negative:
        return list(BloodType)
    elif donor == BloodType.A_positive:
        return [
            BloodType.A_positive,
            BloodType.AB_positive
        ]
    elif donor == BloodType.B_positive:
        return [
            BloodType.B_positive,
            BloodType.AB_positive
        ]
    elif donor == BloodType.AB_positive:
        return [
            BloodType.AB_positive
        ]
    elif donor == BloodType.O_positive:
        return [
            BloodType.A_positive,
            BloodType.B_positive,
            BloodType.AB_positive,
            BloodType.O_positive
        ]

The second one does exactly the same as the first one, but have some big advantages:

  • Help you to avoiding mistakes.
  • Help to code editor to warning if you make a mistake.
  • Help to the next person to works in the code, avoid mistakes.

See the first version again: It has a typo error, a 0 instead of a O.

This post is licensed under CC BY 4.0 by the author.

-

-

Trending Tags