faqts : Computers : Programming : Languages : Python : Common Problems

+ Search
Add Entry AlertManage Folder Edit Entry Add page to http://del.icio.us/
Did You Find This Entry Useful?

0 of 1 people (0%) answered Yes
Recently 0 of 1 people (0%) answered Yes

Entry

Searching a dict and placing into variables?

Feb 12th, 2007 07:12
stephen brown, Andrew Smith, Mr LoL,


I'm trying to take the following dictionary:
NETGROUP = { 'SOME1': '/etc/blah1', 'SOME2': '/etc/blah2'' }
So my script asks for command line input, so if user types SOME1, then a
path variable should equal /etc/blah1, and respectively /etc/blah2
should be set as a variable if the user types SOME2.
I'm having a hard time sucking in the proper values, any help is
appreciated.
--
Does this help?
import sys
path = NETGROUP[sys.argv[1]]
I'm not completely sure I understand the problem.
--
I take it you want to pick from a `menu' of choices (the dictionary)
based on a string entered by the user.  You can look up values in a
dictionary by their key just as you do with an array:
>>> NETGROUP = { 'SOME1': '/etc/blah1', 'SOME2': '/etc/blah2' }
>>> NETGROUP['SOME1']
'/etc/blah1'
>>>
But this is unwise to do with user input because you have no control
over what the user enters, and no guarantee that the key they type is
actually in the dictionary.  You either need to do some extensive
checking on the input before looking it up in the dictionary, or be
prepared to catch the KeyError exception:
>>> NETGROUP['SOEM1']
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in ?
    NETGROUP['SOEM1']
KeyError: 'SOEM1'
>>> 
You perhaps want to use the get() method of the dictionary, which allows
an alternative value to be returned if the key isn't present:
>>> NETGROUP.get('ANY1', '/default/path')
'/default/path'
>>> 
But this isn't always user-friendly--they usually expect an error if
they mistype a choice.
All this begs a broader question, that using arbitrary text strings
entered by a user to make decisions in code is perilous.  Humans are
notoriously unreliable sources of data.  Restricting the scope of
possible inputs (e.g. a list of menu options, indexed by a finite whole
number) can make the interface a lot more robust, and the checking easier.
For instance, this little program:
NETGROUP = { 'SOME1': '/etc/blah1', 'SOME2': '/etc/blah2' }
path = ''
while path=='':
    response = raw_input('Select a path:')
    try:
        path=NETGROUP[response]
    except KeyError:
        print 'Invalid entry, try again.'
print 'Path is %s' % path
is fairly robust, but will quickly drive users crazy unless they've
memorized the first line of your code.  You'd be better off asking them
to enter the path directly.  A simple set of enumerated choices is
easier to enforce robustly:
PATHS = ['/etc/blah1', '/etc/blah2']
path=''
while path=='':
    print 'Path choices:'
    for idx in range(0,len(PATHS)):
        print '\t%d) %s' % (idx, PATHS[idx])
    response = raw_input('Make choice (%d-%d): ' % (0, len(PATHS)-1))
    try:
        idx = int(response)
        if idx<0 or idx>=len(PATHS):
            print 'Invalid choice, try again'
        else:
            path=PATHS[idx]
    except ValueError:
        print 'Enter an integer between 0 and %d, please' % (len(PATHS)-1)
print 'Path is %s' % path
Identify valid inputs to the user, force the input to be concise ('cause
the less they type, the fewer mistakes they make), check the input, and
tell them what they did wrong if they screwed up.