HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Avoiding numbness with Python Enum

Submitted by: @import:stackexchange-codereview··
0
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 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 StarlabCommand Enum 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 (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 Starlab from the Enum class names



  • remove Command from the Enum class names



  • remove make from 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.