Command line with Python

I'm developing a simple project with the purpose or learning Python, actually I have version 3.6 and I wanted to build a command line tool to generate password with specific criteria. So fare here is what I got:

import argparse
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument("-a", "-auto", help="auto mode", action="store_true")
group.add_argument("-m", "-manual", help="manual mode", action="store_true")
parser.parse_args() 

the dead end is I have no idea how to limit a command, example -l -lenght to the reqisite of having -m another stop is, how do I define -l so that it can accept a value, for example -l:8 to specify a password of 8 characters, I also want to put a range limit on -l values, example -l:8-256 and finally, I dont understand the difference between - and -- when defining the parameters.

I have already done all the part of generating passwords, just need a way to control its flow from outside so implementing parameters looked like a good way of doing this.

Upvotes: 1

Views: 104

Answers (2)

chepner
chepner

Reputation: 531125

You can define a custom type to check for valid values:

from argparse import ArgumentTypeError

def passwd_len(s):
    try:
        s = int(s)
    except ValueError:
        raise ArgumentTypeError("'%s' is not an integer" % (s,))

    if not (8 <= s <= 256):
        raise ArgumentTypeError("%d is not between 8 and 256, inclusive" % (s,))

    return s

parser.add_argument("--length", "-l", type=passwd_len)

The difference between -- and - is one of conventions. Historically, options were single-letter arguments prefixed with a -, and groups of options could be combined: -ab was the same as -a -b. In order to support that convention and allow longer option names, a new convention of using -- to prefix multi-character names was devised. --length is a single option, not a group of six options -l, -e, -n, -g, -t, and -h. Long options cannot be grouped.

I would define the -a and -m options like this:

group = parser.add_mutually_exclusive_group()
group.add_argument("-a", "--auto", help="auto mode", action="store_const", const="auto", dest="mode")
group.add_argument("-m", "--manual", help="manual mode", action="store_const", const="manual", dest="mode")
group.add_argument("--mode", choices=["auto", "manual"])

Now instead of having two Boolean attributes that can never have the same value, you have just one attribute whose value you can check directly. Think of --mode as being the canonical way of choosing a mode, with -a and -m as shortcuts for selecting a specific mode.

Upvotes: 1

Keegan Ferrett
Keegan Ferrett

Reputation: 374

What you are looking for is the choices option.

add_argument('--length', type=int, choices=range(8,257)

This will only accept integer values between 8 and 256 (inclusive).

As for your second question, - indicates the shorthand for an option, which is common in most CLI tools, well -- indicates the long hand. It is common practice is CLI tools to provide both a long and a short hand for options.

Upvotes: 2

Related Questions