0

I am working my way through the book Core Python Programming. Exercise 2_11 instructed to build a menu system that had allowed users to select and option which would run an earlier simple program. the menu system would stay open until the user selected the option to quit. Here is my first working program.

programList = {1:"menu system", 
    2:"for loop count 0 to 10", 
    3:"positive or negative", 
    4:"print a string, one character at a time", 
    5:"sum of a fixed tuple", 
    "x":"quit()", 
    "menu":"refresh the menu"}
import os
for x in programList:
    print(x,":",programList[x])

while True:
    selection = input("select a program: ")
    if selection == "1":
        os.startfile("cpp2_11.py")

    elif selection == "2":
        os.startfile("cpp2_5b.py")

    elif selection == "3":
        os.startfile("cpp2_6.py")

    elif selection == "4":
        os.startfile("cpp2_7.py")

    elif selection == "5":
        os.startfile("cpp2_8.py")

    elif selection == "menu":
        for x in range(8): print(" ")
        for x in programList:print(x,":",programList[x])

    elif selection == "X":
        break

    elif selection == "x":
        break

    else:
        print("not sure what you want")
input()
quit()

This version worked fine, but I wanted to use the a dictionary as a case/switch statement to clean up the ugly if/elif/else lines.

Now I'm stuck. I'm using Eclipse with PyDev and my new code is throwing an error:

Duplicated signature:!!

Here's a copy of my current code:

import os

def '1'():
    os.startfile("cpp2_11.py")
def '2'():
    os.startfile("cpp2_5b.py")
def '3'():
    os.startfile("cpp2_6.py")
def '4'():
    os.startfile("cpp2_7.py")
def '5'():
    os.startfile("cpp2_8.py")
def 'm'():       
    for x in range(8): print(" ")
    for x in actions:print(x,":",actions[x])
def 'x'():
    quit()
def errhandler():    
    else:
        print("not sure what you want")


actions = {1:"menu system",
    2:"for loop count 0 to 10", 
    3:"positive or negative", 
    4:"print a string, one character at a time", 
    5:"sum of a fixed tuple", 
    "X":"quit()", 
    "menu":"refresh the menu"}

for x in actions:
    print(x,":",actions[x])

selectedaction = input("please select an option from the list")
while True:
    actions.get(selectedaction,errhandler)()
input()
quit()

I'm pretty sure that my current problem (the error codes) are related to the way I'm trying to use the os.startfile() in the functions. Maybe I'm way off. Any help is appreciated.

EDIT: I am changing the title to make it more useful for future reference. After a helpful comment from Ryan pointing out the simple error in function naming, I was able to piece together a script that works. sort of...Here it is:

import os

def menu_system():
    os.startfile("cpp2_11alt.py")
def loopCount_zero_to_ten():
    os.startfile("cpp2_5b.py")
def positive_or_negative():
    os.startfile("cpp2_6.py")
def print_a_string_one_character_at_a_time():
    os.startfile("cpp2_7.py")
def sum_of_a_tuples_values():
    os.startfile("cpp2_8.py")
def refresh_the_menu():       
    for x in range(4): print(" ")
    for y in actions:print(y,":",actions[y])
    for z in range(2): print(" ")
def exit_the_program():
    quit()
def errhandler():    
    print("not sure what you want")

actions = {'1':menu_system,
    '2':loopCount_zero_to_ten, 
    '3':positive_or_negative, 
    '4':print_a_string_one_character_at_a_time, 
    '5':sum_of_a_tuples_values, 
    'x':exit_the_program, 
    'm':refresh_the_menu}

for item in actions:
    print(item,":",actions[item])
for z in range(2): print(" ")    

selectedaction = input("please select an option from the list:    ")
while True:
    actions.get(selectedaction,errhandler)()
    selectedaction = input("please select an option from the list:    ")
quit()

There were many problems with the second attempt. I was referencing the dictionary key instead of the value when calling functions. I also had some bugs in the way the menu printed and handled input values. Now all I need to do is figure out how to get the dictionary values to print without all of the extra information: This is the output when I print the menu:

2 : <function loopCount_zero_to_ten at 0x027FDA08>
3 : <function positive_or_negative at 0x027FD810>
1 : <function menu_system at 0x027FD978>
4 : <function print_a_string_one_character_at_a_time at 0x027FD930>
5 : <function sum_of_a_tuples_values at 0x027FD780>
x : <function exit_the_program at 0x027FD858>
m : <function refresh_the_menu at 0x027FD7C8>

AND how to get the menu to print in numeric order.

Once again, any help is appreciated.

B-Rell
  • 638
  • 3
  • 7
  • 16
  • 1
    `def '1'():` this isn't a valid function declaration, you need to use a name, not a string like `def one():` – Ryan Haining Apr 21 '13 at 18:19
  • Thank you for that observation. Since I'm fairly new to Python and programming in general, I had overlooked the possibility that the function name was the problem. The code still doesn't work, but this did help me work through the current problem. – B-Rell Apr 21 '13 at 22:00

1 Answers1

0

I finally found a solution to the problem of sorting a dictionary and printing the function names as a string. In the last part of the edited question (3rd code section), I had the fixed code for the question that started this post: how to use integers in a dictionary to create a menu - with the intention of creating a switch/case style alternative and avoiding the ugly if/elif/else problems in the first code section.

Here's the final version of the working code:

import os

def menu_system():
    os.startfile("cpp2_11alt.py")
def loopCount_zero_to_ten():
    os.startfile("cpp2_5b.py")
def positive_or_negative():
    os.startfile("cpp2_6.py")
def print_a_string_one_character_at_a_time():
    os.startfile("cpp2_7.py")
def sum_of_a_tuples_values():
    os.startfile("cpp2_8.py")
def refresh_the_menu():       
    for x in range(4): print(" ")
    for key in sorted(actions):
        print (key, '=>', actions[key].__name__)
    for z in range(2): print(" ")
def exit_the_program():
    quit()
def errhandler():    
    print("not sure what you want")

actions = {'1':menu_system,
    '2':loopCount_zero_to_ten, 
    '3':positive_or_negative, 
    '4':print_a_string_one_character_at_a_time, 
    '5':sum_of_a_tuples_values, 
    'x':exit_the_program, 
    'm':refresh_the_menu}

for key in sorted(actions):
    print (key, '=>', actions[key].__name__)

selectedaction = input("please select an option from the list:    ")
while True:
    actions.get(selectedaction,errhandler)()
    selectedaction = input("please select an option from the list:    ")
quit()

adding the .__name__ method allowed me to print the function names as a string.

Using the for loop:

 for key in sorted(actions):
        print (key, '=>', actions[key].__name__)

created the ability to sort the dictionary.

B-Rell
  • 638
  • 3
  • 7
  • 16