patternpythonMinor
Avoiding numbness with Python Enum
Viewed 0 times
withenumpythonnumbnessavoiding
Problem
First, the context:
I'm working with a student to build a web frontend for a star cluster simulation package called starlab. Typical
The specific piece of the puzzle I'm asking about here is representing the commands. Each command has a different set of arguments, some of which take values and others don't. Additionally, some of the commands have arguments for which defaults aren't supplied, so they need to be included.
Since the commands form a predefined, discrete set, it seemed appropriate to use an Enum. Currently, I keep the commands and their arguments separate (stored in the Run object as tuples). Typical usage would look something like:
My questions:
The code:
```
from enum import Enum
class StarlabCommand(Enum):
"""Enumerator class for starlab commands.
Each member takes three parameters:
1. A dictionary of required arguments (with default values),
2. A list of optional arguments that take a value, and
3. A list of optional arguments that don't take a value.
If there are parameters which are not, strictly speaking, required
(i.e., the underlying starlab command will execute without them being
supplied) but I want to make sure they get into the database, I will
include them in the required list. The most common example of this is
random seed for those commands th
I'm working with a student to build a web frontend for a star cluster simulation package called starlab. Typical
starlab usage involves chaining sequences of commands together with Unix pipes. We want to store both the output and the set of commands (and arguments) used to generate the output in a database.The specific piece of the puzzle I'm asking about here is representing the commands. Each command has a different set of arguments, some of which take values and others don't. Additionally, some of the commands have arguments for which defaults aren't supplied, so they need to be included.
Since the commands form a predefined, discrete set, it seemed appropriate to use an Enum. Currently, I keep the commands and their arguments separate (stored in the Run object as tuples). Typical usage would look something like:
foo = Run()
foo.set_creation_command(StarlabCreationCommand.makeking, **makeking_args)
foo.set_transform_command(StarlabTransformationCommand.scale, **scale_args)
...
commands = foo.generate_command_list()My questions:
- Does this seem like a reasonable approach to this problem?
- Should I roll the argument handling into the
StarlabCommandEnum class, rather than storing the arguments in a tuple/dictionary?
- Is there anything here that could be improved?
The code:
```
from enum import Enum
class StarlabCommand(Enum):
"""Enumerator class for starlab commands.
Each member takes three parameters:
1. A dictionary of required arguments (with default values),
2. A list of optional arguments that take a value, and
3. A list of optional arguments that don't take a value.
If there are parameters which are not, strictly speaking, required
(i.e., the underlying starlab command will execute without them being
supplied) but I want to make sure they get into the database, I will
include them in the required list. The most common example of this is
random seed for those commands th
Solution
The primary reason for using Enums for anything is to give names to constants; this allows easier specification when coding (
Given that each command is represented separately, along with its flags and options, I think you're okay here.
The only constructive criticism I would offer:
With those changes code might look like:
Which should help keep the lines from getting too long (and numbing... and save on the wrists ;) .
StarlabIntegrationCommand.kira instead of ...?), and nicer reprs and easier debugging because you get the name instead of a number, or whatever.Given that each command is represented separately, along with its flags and options, I think you're okay here.
The only constructive criticism I would offer:
- name the module starlab
- remove
Starlabfrom the Enum class names
- remove
Commandfrom the Enum class names
- remove
makefrom enum member names
- possibly rename Enums from nouns to verbs
With those changes code might look like:
from starlab import Create, Transform, Integrate, Run
foo = Run()
foo.set_creation_command(Create.king, **makeking_args)
foo.set_transform_command(Transform.scale, **scale_args)
foo.set_transform_command(Transform.mass, **mass_args)
...
commands = foo.generate_command_list()Which should help keep the lines from getting too long (and numbing... and save on the wrists ;) .
Code Snippets
from starlab import Create, Transform, Integrate, Run
foo = Run()
foo.set_creation_command(Create.king, **makeking_args)
foo.set_transform_command(Transform.scale, **scale_args)
foo.set_transform_command(Transform.mass, **mass_args)
...
commands = foo.generate_command_list()Context
StackExchange Code Review Q#120471, answer score: 2
Revisions (0)
No revisions yet.