2

I'm pretty new to Python and want to keep everything as "Pythonic" as I can in an application I am writing.

I am using docopt which allows me to define my command line arguments and structure at the top of my program in the Usage section. All the arguments are saved in a dictionary.

Then I need to sort out exactly what it is the User wants to do and what parameters or options they have provided for the operation.

Here is some sample code:

""" Test program

Usage:
  plci.py move (user) <id> <source> <destination>
  plci.py remove user (--id=TARGET|--username=TARGET) <source_account>
"""


import requests
import sys
import os.path

try: import simplejson as json
except ImportError: import json

import user_operations
import ConfigParser 
from docopt import docopt
import recovery


if __name__ == '__main__':

    config = ConfigParser.ConfigParser()
    config.read("pcli.sysconf")

    #Headers
    headers = {'Content-Type':'application/json','Accept':'application/json'}

    #Config variables
    appid           = config.get("Config", "appid")
    api_root        = config.get("Config", "api_root")
    secret          = config.get("Config", "secret")
    auto_recovery   = config.getboolean("Config", "auto_recovery")
    token_duration  = config.get("Config", "token_duration")

    arguments = docopt(__doc__, version='1.0.0rc2')
    print(arguments)

    token, scope = user_operations.get_auth_token_and_scope(api_root, appid, secret, token_duration, headers)

    if arguments['remove']:

        if arguments['user']:

            if arguments['--id'] is not None:

                print "YAY, now we know that we want to remove a user being identified by their id num which is " + arguments['--id']

            if arguments['--username'] is not None:

                print "YAY, now we know that we want to remove a user being identified by their username which is " + arguments['--username']

Where the input would look like:

remove user 10 --username=testuser01

The output of this would look like:

{'--id': None,
 '--username': 'testuser01',
 '<destination>': None,
 '<id>': None,
 '<source>': None,
 '<source_account>': '10',
 'move': False,
 'remove': True,
 'user': True}

YAY, now we know that we want to remove a user being identified by their username which is testuser01

Is there another / better way to look through the arguments dictionary and select an appropriate function?

Edit

    if arguments['remove'] and arguments['user'] and arguments['--id']:
       print "YAY, now we know that we want to remove a user being identified by their id num which is " + arguments['--id']

    if arguments['remove'] and arguments['user'] and arguments['--username']:
       print "YAY, now we know that we want to remove a user being identified by their username which is " + arguments['--username']

I have this but there is still a lot of code repetition...

TomSelleck
  • 6,706
  • 22
  • 82
  • 151
  • 1
    having `remove` and `user` be separate arguments seems weird. Is there anything else valid that one can `remove`? – roippi Jan 21 '14 at 17:52
  • I always use [argparse](http://docs.python.org/3.3/library/argparse.html), which keeps the help/parsing in one place (like docopt), but does it from the other side (which I would consider less ambiguous). – mojo Jan 21 '14 at 17:53
  • as for nesting, you can combine conditions using `and` – njzk2 Jan 21 '14 at 17:54
  • Adding on to @mojo's comment, argparse allows you to define subcommands for which you can define a separate set of positional arguments and options and thus simplify processing `move` and `remove`. – Matt Briançon Jan 21 '14 at 18:50
  • @roippi, when more functionality is added, other types of objects can be removed from the database. mojo and Matt, I am pretty set on using docopt - check this out if your interested http://tinyurl.com/pe8rbtq – TomSelleck Jan 22 '14 at 09:37
  • You could use `all(a in arguments for a in ['remove', 'user', '--id'])`, but actually I don't see a problem with both of your variants in the first place... – tobias_k Jan 22 '14 at 12:14
  • @tobias_k I'll take a look at that, I have a similar question [here](http://stackoverflow.com/questions/21047024/turn-if-elseif-statements-into-dictionary) and thought maybe there was something similar I could do. – TomSelleck Jan 22 '14 at 12:19

0 Answers0