Python console menu using a dictionary - python

I'm building a Windows application using Python 2.7 that requires a simple console menu, ex:
Do something
Do something else
Exit
There will be several menus, the main menu will link to others. So I am attempting to avoid the scenario of having a bunch of stacks of if input == "1" code. Similar to this StackOverflow link. My below code is currently skipping the main menu and executing every option in my second menu. I've looked it over but I'm failing to see the logic in why it is performing the way it does.
computer = ""
# need a class for each of the options in power_menu
class power:
def logoff(self, computer):
print "logging off " + computer
def restart(self, computer):
print "restarting " + computer
def shutdown(self, computer):
print "shutting down " + computer
def set_computer():
global computer
#os.system("cls")
# optionally print the banner
computer = raw_input("Computer: ")
# check the computer is online
# move to the main menu with the computer parameter
menu().menu_main(computer)
def func_quit():
sys.exit()
def invalid(computer):
#os.system("cls")
print "INVALID CHOICE!"
menu().menu_main(computer)
class menu():
def menu_main(self, computer):
opts_main = {"1":("Power Options", self.menu_power(computer)),
"2":("Service Options", self.menu_service(computer)),
"3":("Service Tag & Warranty", self.menu_warranty(computer)),
"4":("User Options", self.menu_user(computer)),
"5":("Change Computer", set_computer),
"6":("Quit hd-con", func_quit)
}
for key in sorted(opts_main.keys()):
print "\t" + key + ": " + opts_main[key][0]
ans = raw_input("Selection: ")
try:
opts_main.get(ans, [None, invalid])[1]()
except Exception, e:
print e
#men_sel()
def menu_power(self, computer):
opts_power = {"1":("Logoff", power().logoff(computer)),
"2":("Restart", power().restart(computer)),
"3":("Shutdown", power().shutdown(computer)),
"4":("Main Menu", menu.menu_main),
"5":("Quit hd-con", func_quit)
}
for key2 in sorted(opts_power.keys()):
print "\t" + key2+": " + opts_power[key2][0]
ans2 = raw_input("Selection: ")
try:
opts_power.get(ans2)[1]()
#pow_sel()
except:
raise
My output for the above is looking like this.
Computer: asdf
logging off asdf
restarting asdf
shutting down asdf
1: Logoff
2: Restart
3: Shutdown
4: Main Menu
5: Quit
Selection:
I'm looking for guidance on using a dictionary for use in a console menu, fixes for the existing code, or a recommended direction to take this instead of what i'm looking at.
Thanks in advance.

Your assignment to the dictionary:
opts_main = {"1":("Power Options", self.menu_power(computer)), ...}
is calling menu_power, and storing the return value (None) in the tuple. You can use e.g. functools.partial to avoid this:
from functools import partial
opts_main = {"1":("Power Options", partial(self.menu_power, computer)), ...}

Related

How to make "menus" without functions or not call them inside eachother?

Im learning python and I already know the basics. So i'm trying to make a simple program: "A note pad".
Im only using the console and I want to have the following menus
main menu, read note menu, write menu, etc. To do that i'm using a function for each menu, printing the menu, using input() to choose the next menu and then I call the function of the next menu.
But if I have a try / except block in a "a menu", and there's an error in another function called inside that block it will go back and execute the except block.
How can might I be able to avoid this, or is there any better way to make the menus?
Here's what I have:
noteList = [["Here goes the title", "Here goes the text", "Here goes the date"], ["Example", "Text Text Text Text Text Text Text Text", "08/08/2020"]] # note list
#-------------Main Menu-------------
def mainMenu():
print(*"NOTES") # title
print("Write:")
print('-The number of the note to read;')
print('-[N] to create a [N]ew note;')
print('-[D] to [D]elete a note;')
print('-[E] to [E]xit;')
# saved notes
if len(noteList) == 0: # no saved notes
print("\nYou have no notes.")
else: # display saved notes
print("\nSaved notes:")
for number in range(len(noteList)):
print(str(number + 1) + "-" + noteList[number][0])
# ask what action to do
action = input()
actionChooser(action)
#-------------Action Chooser-------------
def actionChooser(action):
try:
action = int(action) - 1 # action is int
readNote(action)
except:
if action == "N" or action == "n": # action is N
newNote()
elif action == "D" or action == "d": # action is E
deleteNote()
elif action == "E" or action == "e": # action is S
exit()
else: # invalid action
print("Invalid action.\n")
mainMenu()
#---------------------------------------
def readNote(noteNumber):
print(*"\n" + noteList[noteNumber][0].upper())
print(noteList[noteNumber][1])
mainMenu()
Thanks and my apologies if I have accedently broken one of your rules it's my first post here.
I will describe how I see it in pseudocode:
1. start program
2. defining processing functions
3. print instructions
4. endless loop
5. wait for input
6. action with try/except
7. exit program
And example program:
import sys
def action_howto():
print("""Instructions:
'test' for action_test
'exit' for exit
""")
def action_test():
print("action_test executed\n")
def action_exit():
sys.exit("bye-bye")
def do_action(action):
try:
{
"test": action_test,
"exit": action_exit
}.get(action.lower(), action_howto)()
except Exception as e:
action_howto()
def main():
action_howto()
while True:
action = input()
do_action(action)
if __name__ == "__main__":
main()

Python calling PyFIles

How Can I call a Python Script From anonther Python Script
I tried using os system and tried using this
def run(runfile):
with open(runfile,"r") as rnf:
exec(rnf.read())
print ("Welcome")
print ("Programs.")
print ("1. Vowel Counter")
print ("2. Basic Calculator")
print ("3. Odd Even")
program = int(input("Select a Program by Choosing its number: "))
programs = ["1", "2", "3"]
if program == "1" :
execfile('VowelCounter.py')
There's no Error but it wont run the other py file
Even though python has the capabilities to run external script using exec and execfile, the more pythonic way of doing is by importing packages.
But I understand that you target can only be known at run time, you could use importlib, to import a package dynamically.
A sample is given below
# Order should be re arranged as per your need
programs = {
"1": {'package': "VowelCounter", "desc": "1. Vowel Counter"},
"2": {'package': "BasicCalculator", "desc": "2. Basic Calculator"}
}
for item in programs.values():
print(item['desc'])
program_idx = input("Select a Program by Choosing its number: ")
imp_module = importlib.import_module(programs[program_idx]['package'])
main_method = getattr(imp_module, "main")
main_method()
You are reading the program variable as int here
program = int(input("Select a Program by Choosing its number: "))
Then you are checking the value as string
if program == "1" :
It must be
if program == 1 :
I think that should be the problem. If not you will get the real problem after this!
import os
print("Welcome")
print("Programs.")
print("1. Vowel Counter")
print("2. Basic Calculator")
print("3. Odd Even")
program = input("Select a Program by Choosing its number: ")
programs = ["1", "2", "3"]
program_files = {'1': 'VowelCounter', '2': 'BasicCalculator', '3': 'OddEven'}
if program in "123" :
cmd = f'python {program_files[program]}.py'
print('Running -->', cmd)
os.system(cmd)

Getting my Python program to run Power Shell Script

Hello please forgive me if my question duplicate, I've searched previous questions and nothing seems to be quite the same. I'm working on a program that will scan a specific folder and search for specific file types to create a menu for a user to select. Once the user select the menu option the the corresponding file which is a power shell script. Currently My program does everything but run even a simple power shell script. I've attempted several configuration and it's not working. It would be great if someone can see what I may be doing wrong or provide me with some pointers. Code below.
##Text Menu Dynamic test
##version 1
## Created By Dragonshadow
## Code produce in Notpad++ For python v3.4.4
import os
import subprocess
import time
import pathlib
import logging
import fnmatch
import re
## Directory Enumerator
fileFolderLocationFilter = fnmatch.filter(os.listdir('C:\\Users\\myfolder\\Documents\\Automation_Scripts\\ENScripts\\'),"*.ps1")
selectedFile=""
## Menu defined setting veriables
def ENOC_menu():
files = fileFolderLocationFilter
counter = 1
print (20 * "=" , "Enoc Quick Menu" , 20 * "=")
enumFiles = list(enumerate(files))
for counter, value in enumFiles:
str = repr(counter) + ") " + repr(value);
print(str)
str = repr(counter+1) + ") Exit";
print(str)
print (57 * "_")
str = "Enter your choice [1 - " + repr((counter+1)) + "]:"
choice = int(input("Please Enter a Selection: "))
selectedFiles = enumFiles[choice]
return(selectedFiles[1])
if choice > counter :
choice = -1
elif choice != counter :
print("Please selecte a valid choice")
else:
selectedFiles = enumFiles[choice]
print(selectedFiles[1])
##selectedFiles = selectedFiles[1]
return choice
def you_sure():
opt = input("Are you sure Yes or No: ")
if opt=="Yes":
print("Continuing please wait this may take a moment...")
elif opt=="No":
print("returnig to Enoc Menu")
else: ##Stays in loop
print ("Please choose yes or no")
##count_down
def count_down ():
count_down = 10
while (count_down >= 0):
print(count_down)
count_down -= 1
if count_down == 0:
print("Task will continue")
break
##initiating loop
loop = True
while loop:
choice = ENOC_menu()
print ("\n" +"You selected "+ choice +"\n")
subprocess.call("C:\\WINDOWS\\system32\\WindowsPowerShell\\v1.0\\powershell.exe" + choice, shell=True)
##print ("---" +str(selectedFile))
You have probably already figured this out, but I the problem is in the subprocess.call() line. You are concatenating the powershell.exe path and the target file name together. See here:
>>> scriptToRun = "c:\\users\\Username\\Documents\\WindowsPowerShell\\classtestscript.ps1"
>>> powershellExe = "c:\\windows\\system32\\windowspowershell\\v1.0\\powershell.exe"
>>> print(powershellExe + scriptToRun)
c:\windows\system32\windowspowershell\v1.0\powershell.exec:\users\Username\Documents\WindowsPowerShell\classtestscript.ps1
Above, the two strings are stuck together without a space between them. Windows can't make sense of what you're trying to execute.
Put a space between the two two and subprocess.call() will understand what you're trying to do:
>>> print(powershellExe + ' ' + scriptToRun)
c:\windows\system32\windowspowershell\v1.0\powershell.exe c:\users\Username\Documents\WindowsPowerShell\classtestscript.ps1

Running code through iPython or command window by double clicking

When coding with Python, I've been using Spyder (as it came part of the package that I needed for work)
It comes with an editor, and of course a console, so I write my code and then run it there also.
It looks like this for those who are unfamiliar:
Here I can run my code no problem and get no errors.
Of course, I also save this code to a file, and I would like to get that code running by just double-clicking on the file name. Is that possible?
I can do it now and get a command prompt, but when I do it now I get this error:
(I'm using the same code that's in the images, can anyone tell me what I am doing wrong?
Here is my clear() code in case that matters:
def clear():
os.system(['clear','cls'][os.name =='nt'])
Edit:
Here's the last portion of the code, since the pictures are hard to read.
player = raw_input("What is your name? ")
The game itself
def hangman(player):
clear()
print "Hello! \nWelcome to Hangman, %s" % player
if init_play() == "quit":
print "Ok. Goodbye"
return
word = word_gen("text")
word_hidden = ["-" for x in range(0,len(word))]
av_letters = [chr(x) for x in range(97,123)]
guessed = []
turn = 1
print ("I am thinking of a word that is %d letters long\n" % len(word))
print "Here is the board\n"
print_board(word_hidden)
print "\nHere are your available letters:\n"
show_letters(av_letters)
while turn <= 5:
if word_hidden.count("-") == 0:
print "\nYou won!"
play_again()
print "\nGuess %d out of %d\n" % (turn, 5)
turner = word_hidden.count("-")
guess = raw_input("Guess a letter! ")
als = av_letters.count(guess)
guess_check(guess, guessed, word, word_hidden, turn, av_letters)
if als == 0:
pass
elif word_hidden.count(guess) == 0:
turn+=1
print ("You lose.\nThe word was %s\n" % word)
print ""
play_again()
clear()
hangman(player)
To use os.system, you need to import the os module first. The code is missing the import statement.
Put the following line at the beginning of the code:
import os

Im making an animation studio/viewer with python

Okay, so im making an animation thing where you like can wiew built-in animations or make your own, and this is the code so far:
import time
def bi2():
print """\ \ \ """
time.sleep(.5)
print """ \ \ \ """
time.sleep(.5)
print """ \ \ \ """
time.sleep(.5)
print """ \ \/ """
time.sleep(.5)
print """ \/\ """
time.sleep(.5)
print """ /\/ """
time.sleep(.5)
print """ / /\ """
time.sleep(.5)
print """ / / / """
time.sleep(.5)
print """ / / / """
time.sleep(.5)
proceed1234 = raw_input("| | |")
if proceed1234 == "q":
main_menu()
elif proceed1234 == "b":
animations1()
else:
time.sleep(.5)
bi2()
def play2():#2nd built in
print "Type in 'q' at any time possible to return to the main menu, or 'b' to go to the animations menu."
bi2()
def bi1():
print " | "
time.sleep(.5)
print " |"
time.sleep(.5)
print """ /\"""
time.sleep(.5)
print ''' / \'''
time.sleep(.5)
print " | OO |"
time.sleep(.5)
print ''' \ /'''
time.sleep(.5)
print ''' \/'''
time.sleep(.5)
print " |"
proceed123 = raw_input(" |")
if proceed123 == "q":
main_menu()
elif proceed123 == "b":
animations1()
else:
time.sleep(.5)
bi1()
def play1(): #first built in animation
print "Type in 'q' at any time possible to return to the main menu, or 'b' to go to the animations menu."
bi1()
def animations1(): #pre made animations
print "You are now viewing the pre-made animations."
time.sleep(1)
print "During each animation, hold down enter for the animation to play, or type 'q' then enter to quit."
time.sleep(1)
animation_choice = raw_input("Type in '1' for animation 1, '2' for animation 2, or 'q' to go back to the main menu.: ")
if animation_choice1 == "1":
play1()
elif animation_choice1 == "2":
play2()
elif animation_choice1 == "q":
main_menu()
else:
print "Invalid choice, check spelling and try again."
animations1()
def main_menu():
print "Type in 'q' to quit the program."
print "Type in 'v1' to choose between 2 pre-made animations."
print "Type in 'as' to go to the animation studio."
print "Type in 'v2' to view your custom animations."
choice = raw_input("Or type in 'b' to go back to the explaination of this program.: ")
if choice == "b":
explaination()
elif choice == v1:
animations1() #animations1 is the pre-made one
elif choice == "as":
animation_studio()
elif choice == "v2":
animations2() #animations2 is the custom user-made animations
elif choice == "q":
quitcheck = raw_input("Are you sure you would like to exit the program? (type 'y' or 'n'): ")
if quitcheck == "y":
print "Goodbye."
time.sleep(2)
elif quitcheck == "n":
main_menu()
else:
print "Invalid choice (check spelling/case), returning to main menu ..."
time.sleep(1)
main_menu()
else:
print "Invalid choice, please check your spelling and try again."
main_menu()
def explaination():
print "Welcome to the animation viewer/maker!"
time.sleep(1)
print "In the main menu, you can select what you would like to do."
time.sleep(1)
print "This program uses text characters to animate something in a loop."
time.sleep(1)
print "As long as you don't close this program, it can save 2 different custom animations, and you can view the ones you created or the pre-made ones."
time.sleep(1)
print "With custom animations, you can type anything you want to create animations that loop (see the pre-made ones for ideas/examples). They can be up to 10 lines."
time.sleep(1)
jafsdlk = raw_input("Please press enter to continue.: ")
main_menu()
explaination()
i may have copied the code wrong but i dont know.
anyway, iu havent added the animation studio yet or the ability to make and save custom animations, and its a pretty simple type of program.
but when i put this in notepad and save it as a .py file and run it to test it, i start getting an error when it runs explaination(), it says it has an error with triple quoted strings, but if i make the triple quoted strings with one quote, it gives me EOL while scanning literal, someone help
The backslash \ is an escape character. You typically use it so Python will take the next character literally.
You can prefix the string with r to indicate a raw string or surround it with triple quotes, as you've done. However, you're running into problems with the \ escaping the first " in the close triple-quote of your line, which makes three quotes to open it, and only two to close--which makes it seek out the next ", in the next line, which throws off everything else.
Right:
print r"This works because there's a space after the slash \ "
Wrong:
print r"This doesn't \"
https://docs.python.org/2.7/reference/lexical_analysis.html#string-literals

Categories

Resources