0

I'm working with a python api that has a function that takes an argument for a filter type. The options are as follows:

Metashape.NoFiltering
Metashape.MildFiltering
Metashape.ModerateFiltering
Metashape.AggressiveFiltering

I'm developing a cli that calls this function and have an argument for filtering mode (using argparse) that has str options for "none", "mild", "moderate", "aggressive".

parser.add_argument(
    "--filter-mode",
    choices=["none", "mild", "moderate", "aggressive"],
    default="moderate",
    help="filter mode for depth maps",
)

What would be the best way to map the input string argument to the required filtering type? 2 approaches immediately come to mind for me:

  1. function that converts string to FilterMode
def string_to_filter_mode(string: str) -> Metashape.FilterMode:
    if string == "none":
        return Metashape.NoFiltering
    if string == "mild":
        return Metashape.MildFiltering
    if string == "moderate":
        return Metashape.ModerateFiltering
    if string == "aggressive":
        return Metashape.AggressiveFiltering
    raise ValueError

usage:

chunk.buildDepthMap(filter_mode=string_to_filter_mode(filter_mode))
  1. Create a dictionary mapping string value to type
METASHAPE_FILTER_MODES = {
    "none": Metashape.NoFiltering,
    "mild": Metashape.MildFiltering,
    "moderate": Metashape.ModerateFiltering,
    "aggressive": Metashape.AggressiveFiltering,
}

usage:

chunk.buildDepthMap(filter_mode=METASHAPE_FILTER_MODES[filter_mode])

Both ways seem pretty simple and extendable but which option would be the preferred method for doing this, as the application I'm working on has various similar types of arguments. Or is there a way to handle this directly in argparse?

  • If that didn't answer your question, the `type` argument that your `ArgumentParser.add_argument` method takes is _any callable_ that can take a string, and return _any object_. The `choices` argument is a list of acceptable values, once they have been through this conversion. Simply changing your argument definition to have `type=METASHAPE_FILTER_MODES.get` and `choices=METASHAPE_FILTER_MODES.values()` will result in the dict values being returned in the parsed `Namespace`. – Pranav Hosangadi Jul 27 '22 at 00:16
  • the filter modes aren't Enum types so `list(Metashape.FilterMode)` doesn't work as it does in the answer above – mitchgalea Jul 27 '22 at 00:17
  • right, but recognize that `choices` is _just a regular list_ containing all acceptable choices, Sure, if you have an enum class you can simply do `choices=list(enum)` to get these values, but since you have a dict already, you can do the same with a dict just as easily: `choices=list(METASHAPE_FILTER_MODES.values())` – Pranav Hosangadi Jul 27 '22 at 00:23

0 Answers0