Troubles with global variables

Tim Hochberg tim.hochberg at ieee.org
Wed Oct 17 09:37:32 EDT 2001


Hi Jeremy

"Jeremy Whetzel" <lists at toadmail.com>:wrote in message
news:87g08hr5zc.fsf at toadmail.com...

[SNIP code]
>
> I've been playing around with the code, and I have a couple of
> questions.
>
> First, with the dictionary having tuples, the items in the
> tuples cannot be reassigned. (which is the error I receive when I try to
> change an option)  If I change the tuples to lists, I then receive an
> error saying "TypeError: not enough arguments for format string".  (I
> think I got this one figured out by putting (item[0],item[1],item[2])
> instead of just 'item' on the string formatting line.  What would _you_
> do to change this?  (ie, did I hit close to the mark?)

Use:

print "  %s )  %15s   %s" % tuple(item)

> Also, I've noticed that when the menu prints, it tends to print the menu
> listing in alphabetical order of the keys in menudict.  Is there a way
> to change this behavior?

Dictionary's don't remember the order that items are added, so the order of
items returned by aDict.items() is undefined and the fact that you're
getting them in alphabetical order is an accident of the implementation. If
you want to preserve the order of the keys you're going to need to use a
list/tuple in some manner. One way would be to use:

menulist = [('E', ['E', 'Encoder', 'gogo' ]),
                  ('B' , ['B', 'Bitrate', '128' ]),
                  ('Q' , ['Q', 'Quit', '' ] ) ]
# Generate menudict from menulist so they stay in syc
menudict = {}
for key, value in menulist:
   menudict[key] = value
# Everything else the same except when printing
#...
for key, value in menulist: # use the list for printing
   print "  %s )  %15s   %s" % value
#...

There's no reason to store the 'E', 'B', 'Q' values on both the 'key' and
'values' halves of the dictionary's either -- I would be tempted to rewrite
the function to avoid that.

> One last thing, and this was something I didn't address earlier, but
> having the 'enc' variable is something I need later in the program.  I
> know I could use menudict['E'][2], but that feels cumbersome to type out
> each place I need it.  How would you approach this?

Below is one possible way to rewrite your code that I think address your
(and my)  (well mostly my) concerns expressed above. For the last case, you
would just type data['E'], which seems a little less cumbersome than
menudict['E'][2].

-tim



import os
# Format is (key, name, initvalue)
_menu = [('E', 'Encoder', 'gogo'),
         ('B' , 'Bitrate', '128'),
         ('Q' , 'Quit', '') ]

def showmenu(menu):
    # Build the names and data dicts from menu
    names, data = {}, {}
    for key, name, value in _menu:
        names[key] = name
        data[key] = value
    while 1:
        os.system('clear')
        for key, name, initial in menu:
            print "  %s )  %15s   %s" % (key, name, data[key])
        print
        choice = raw_input('Enter Choice: ').upper()
        print
        if choice == 'Q':
            break
        elif data.has_key(choice):
            prompt = 'Enter the new %s: ' % names[choice]
            data[choice] =  raw_input(prompt)
        else:
            print "That is not a valid option."
    return data

if __name__ == '__main__':
    data  = showmenu(_menu)
    print data





More information about the Python-list mailing list