A global key that that takes you back to menu - python

I have tried to find what I am seeking before posting this. But I have a hard time formulating the question and finding an answer.
I wonder if there is any way of having a key, such as "b", that takes the user back to the main menu where ever he is while running my program.
I have a menu and sub-menus and I want the user to be able to go back to the menu wherever he is by just pressing "b". I wonder if there is any easy way of doing this instead of putting
if choice= b:
menu()
whenever I have an input()...
I hope this is not too confusing! Would really appreciate a answer!

Not recommended for making your code easy to read but...
You could make your 'b' input check a function, then run that function at the start of each input check
def b_check(option):
if option == 'b':
main_menu()
else:
return option
def main_menu():
#your main menu function goes here
#your active menu code goes here
#ask the user to make their selection
#Note: for Python 2.x use `raw_input`
option = input('Enter your choice')
b_check(option)
if option == 'a':
#do this
elif option =='c':
#do that

Related

How to pass input from one entry widget into multiple sequential functions OR how to pass button input into a function

So I essentially have 2 codes at the moment, a text-based game and a GUI, that function separately that I'm trying to combine. The game basically has a series of functions it can call based on user input - eg:
def game():
print("Would you like to play? [Y/N]")
start = inpupt().lower().strip()
if start == 'y':
adventure()
elif start == 'n':
goodbye()
with adventure() calling two or more options leading to their respective functions, etc. etc.
The GUI is tkinter based, has a label, a scrolled text box, an entry widget, and an "enter" button. I've created my own "print" functions that allow the code to input text into the scrolled text box, and then disable the box again, so that the user doesn't directly edit it. I've also been able to have the button/enter key pull text from the entry widget and print it in the text box, and then clear the entry widget.
What I don't know how to do is get the entry widget/button to integrate with the different game functions. It seems like you can set a function for the button - which is how I was able to pull the entry text, but I don't know how to then pass that pulled information on to another function.
I tried something like this which worked for just entering text into the scrollbox with this attached to the button as the command:
def clicked(self, variable, event=None):
self.variable = self.userin.get()
self.print1(self.variable)
self.clear_text()
But then I don't know how to call that as a part of my game function. This was all I could think of (and I know it's wrong and bad, ok?):
def game():
print1("Would you like to go on an adventure? [Y/N]")
clicked(self, start) #trying to use "start" as the variable
if self.start == "y":
self.print1("Let's go!")
elif self.start == "n":
self.print1("Okay, bye!")
else:
self.print1("What?")
But then game() is trying to call the clicked() function instead of waiting for the button, so it's not really pulling the input from the user. I also kept getting the error that "start" was not defined, probably for that reason. (Also please ignore any errors in where "self" is supposed to go... this was my first stab at using classes, and I know I'm probably doing more wrong than right, I'd figure it out if you had a solution in this vein)
So is there a way to get the button to pass the user input into the function, without the function being exclusive to the button? (Like I know I could get it to make one choice, but then how would I get the button to function for the next choice?)
My "Plan B" was to just create buttons for user input - either yes/no or a/b/c/d - so that the function of the buttons would be the same : return "B" (or something like that), but then how would I get the function to pull that input? Or wait for that input?
I have googled this six ways to Sunday, and have not found anything that works for this situation. I thought I'd found something with the CallBack function - but then I realized they were using it for multiple buttons, instead of the same button for multiple functions.
Here is a quick example using some of what you provided that should demonstrate how you can link your conditions for the button. Regardless of how you actually structure your code, the concept should demonstrate one way you could do it. I would look into some tkinter tutorials as these concepts are well documented. I hope this helps.
import tkinter as tk
def clicked():
entry_value = entry.get()
entry.delete("0", tk.END)
print(entry_value)
# set up whatever conditions you want the button to be linked with
if str(entry_value) == "y":
print("Alright, get ready!")
# now you call your function to start the game here
start_game()
elif str(entry_value) == "n":
print("Ok, maybe another time")
label.config(text="Ok, maybe another time, closing the game now")
root.after(2500, lambda: root.destroy())
else:
label.config(text="Invalid entry, please enter a lower case 'y' or 'n'")
label.after(3000, reset_label)
def start_game():
# just an example this creates a new window to simulate some bhavior of the game
top = tk.Toplevel()
top.geometry("500x500")
top.title("New Game")
top.config(bg="blue")
# add things to the toplevel that shows the game? not sure what you want to do
def reset_label():
label.config(text="Would you like to play? [y/n]")
root = tk.Tk()
root.geometry("300x200")
label = tk.Label(root, text="Would you like to play? [y/n]")
label.pack()
entry = tk.Entry(root)
entry.pack()
button = tk.Button(root, text="Go", command=clicked)
button.pack()
root.mainloop()
Thank you for the suggestions! This is what I worked out (once I figured out the right way to change the command - no extra parenthesis!):
def choice1(event=None):
whereto = userin.get().lower().strip()
if whereto == "woods":
print1("The woods are spooky")
button["command"] = woods
elif whereto == "tavern":
print1("The tavern is crowded")
button["command"] = tavern
else:
print1("What?")
print1("Woods or Tavern?")
def clicked(event=None):
start = userin.get().lower().strip()
print1(userin.get())
clear_text()
changelabel("Let's go!")
if start == "y":
print1("Lets go!")
print1("Woods or Tavern?")
button["command"] = choice1
elif start == "n":
print1("Ok bye!")
else:
print1("What?")
print1("Do you want to play a game?")
I'd like to make the return key work the same as the button click, so I suspect I'm going to have to add the root.bind('<Return>', func) everywhere too

Python-Vim function to use arrow keys to select an item from a list

I'm playing around trying to emulate some Ctrl-P-like behaviour in Vim. What I have so far:
User calls my function.
A window is opened with a list of items in it.
A prompt is displayed under the list of items.
I want the user to be able to use the up and down arrows to select from the items but without leaving the prompt (in which they can also type).
I have got 1-3 mostly under control but am struggling with #4. I have got as far as this:
python << EOF
import vim
def MyWindow():
# Create a new window at the bottom
vim.command("below new")
vim.current.buffer.append("123")
vim.current.buffer.append("234")
vim.current.buffer.append("345")
vim.command("redraw")
vim.command("setl cursorline")
vim.command("echon '>> ' | echoh None")
while True:
vim.command("let x = getchar()")
character_code = vim.eval("x")
if character_code == "13":
# Exit by pressing Enter
break
elif character_code == "\x80kd": # Down
vim.command("keepj norm! j")
vim.command("redraw")
EOF
command! MyWindow python MyWindow()
Now the first down arrow keypress works perfectly, but subsequent down arrow kepresses don't, even though the code in the "if down key pressed" case is executed. Any ideas?
I just realised I can make it work by doing this:
elif character_code == "\x80kd": # Down
vim.command("keepj norm! j")
vim.command("setl cursorline") # <-- This fixed it
vim.command("redraw")
But I have no idea why or if this is a sensible thing to do.

Stopping a Python program when a def statement gives a specific result

I am trying to create a task based on the Dragon Realm game in the Invent your Own Games with Python book. The original allows one choice to be made and uses functions to set up those choices. I am trying to allow two separate choices to be made but can't figure out how to stop the task after the first choice if the def statement gives a specific result, ie. if the first choice is the wrong choice then the user does not get to make a second choice. Any help would be much appreciated. Thanks.
import random
import time
def displayIntro():
#introduction
def chooseDoor():
#user chooses door
def checkDoor(chosenDoor):
#checks user choice against random number
if chosenDoor == str(friendlyDoor):
#various good stuff happens
else:
#bad stuff happens
#at this point I would like to go back to the option to play again if they have chosen the wrong door
#but I can't make it work by putting a break here as it goes on to the next def statement (chooseBox)
#this is where the original game finished
def chooseBox():
#user chooses a box but only if they made the correct choice above
def checkBox(chosenBox):
#checks user choice against random number and good or bad stuff happens
playAgain = 'yes'
while playAgain == 'yes' or playAgain == 'y':
displayIntro()
doorNumber = chooseDoor()
checkDoor(doorNumber)
boxNumber = chooseBox()
checkBox(boxNumber)
#play again option
The checkDoor() function should return a True if a friendly door is chosen, False if not. Then, in your main loop, modify
checkDoor()
to
if not checkDoor():
continue
In this way, is the player chooses a non-friendly door, the function returns False, and the "continue" statement will reset the program to the next execution of the while loop. Otherwise, it goes on to chooseBox()

Re-keying a dictionary

So I have a Python assignment where I need to use a dictionary to hold the items of a menu, then randomly re-key and re-order the menu so that I can change the order of the menu options printed out. Here is an example of the code I have:
ChoiceOne = "Rekey Menu"
ChoiceTwo = "Quit"
menu = {'1':ChoiceOne, '2':ChoiceTwo,}
userChoice = input("Please Enter the Integer for Your Menu Choice: ")
while userChoice not in menu.keys():
print("Invalid Input")
userChoice = input("Please Enter the Integer for Your Menu Choice: ")
if menu[userChoice] == ChoiceOne:
menu = rekey(menu)
elif menu[userChoice] == ChoiceTwo:
quit()
The above code loops while the user chooses not to quit, repeatedly printing out the menu over and over again. The following is my rekey() function
def rekey(menu):
rekey = {}
keylist = random.sample(range(10), 2)
for i, item in zip(keylist, menu ):
rekey[i] = menu[item]
return rekey
My problem seems to present itself in the line where I check whether the user input for the menu option is valid or not. Initially, entering anything other than "1" or "2" will cause the program to enter the While loop until a valid input is entered. After rekeying the menu however, the line "while userChoice not in menu.keys()" is always triggered and no input is ever matched to continue the program.
I've tried to find the problem by printing out the new keys in the dictionary and checking to see if the userChoice matches any one of them, but even when I choose a valid new key, the program seems to think that nothing I enter is a valid key.
I hope I've described the problem well enough to be understood, thanks for the help in advance!!
In your first case the menu keys are strings, after the rekey they are ints. You need to do a conversion of either the keys or the user input so they match.
According to the documentation the input(x) function is equivalent to eval(raw_input(x)). This means that typing "1" at the input prompt is equivalent to typing "1" in the python interpreter, so you get the integer 1.
As SpliFF has already pointed out, you need to ensure that you're either using integer keys in your menu dictionary, or you could use string keys for the dictionary and switch to using the raw_input function to read the user's choice.

Stop a Python program until a user performs an action

My original program used input, like this:
n = input("Enter your favorite number: ")
# do stuff with number
Now, I have switched to a GTK GUI, but still want the accomplish the same thing. Now look at this very similar piece of code:
n = myWindow.getNumber()
# do stuff with number
Would it be possible to write a getNumber() method that only returns after the user presses a submit button in the window? (like the how the input function works) or is this my only option:
def callback(widget, event):
n = myWindow.inputWidget.getValue()
# do stuff with number
n = myWindow.getNumber(callback)
Update: I'm looking to do this without a gtk.Dialog, as I don't want a dialog popping up every time user input is required.
What you need is a modal dialog. I don't know GTK (or PyGTK) at all, but there appears to be an example in the documentation.

Categories

Resources