I'm trying to create a function that gets two functions as argument and I get an error .
What I have done is created a function named "parent" that takes 2 functions as argument (ux and ui). But ux has arguments too, and it gets them from the parent function:
import ID_Ui as Ui
ui = Ui.admin_panel()
# ui returns something like this :
'''Please choose one of the options below :
Please press 0 if you want to exit the program .
Please press 1 if you want to exit to main menu .
Please press 2 if you want exit to previous section .
Please press 3 if you want to create/modify user account .
Please press 4 if you want to create/modify company account .
Please press 5 if you want to create/modify document type .
Please press 6 if you want to create/modify document ID . '''
def child(*ui):
user_choice = ui
if user_choice == 3:
return 3
elif user_choice == 4:
return 4
elif user_choice == 5:
return 5
else:
return 'error'
def parent(ux, ui):
user_choice = ui
x = user_choice
if user_choice == 0:
return 0
elif user_choice == 1:
return 1
elif user_choice == 2:
return 2
else:
ux(x)
print(parent(child(), ui))
I expect that when I input a number other than [0:2] , it runs the ux function and passes it the x variable as its argument. But I get the following error regarding ux(x) line:
TypeError: 'int' object is not callable
First of all, I'll assume that the function menu_conditions you are invoking is in fact the parent function, but I believe you should fix that.
Second, when you run child() on the last line, it returns a number, or the string error. If you wanted to be able to run child inside the parent folder, simply pass it without parentheses, like that:
print(parent(child, ui))
Related
Please help me fix this recursive function so that I can successfully prompt the user at each stage. I am trying to make a program that allows users mix, change the playback speed and filter the signal of a wav file. To do that I need create a recursive question that continually prompts the user to use different tools in this program.
def c_function():
print("you have successfully called c_function")# These print statements are just place holders for the actual functions
return
def m_function():
print("you have successfully called m_function")
return
def f_function():
print("you have successfully called f_function")
return
def s_function():
print("you have successfully called s_function")
return
"use these functions as selection tools in the recursive function bellow"
user_question1 = input("Select one of the following four options:\n s see the sample rate of the file\n c change the playback speed\n m mix two signals together\n f filter the signal or\n q quit \n : ")
def recursive_main_function():
if user_question1 == ('c'):
c_function()
recursive_main_function()
if user_question1 == ('m'):
m_function()
recursive_main_function()
if user_question1 == ('f'):
f_function()
recursive_main_function()
else:
print("Invalid response. Please try again" + user_question1)
return
It looks like you'd want to use an infinite while loop. Using if statements with else ifs is good too because if the user input somehow fulfils more than one of the cases, the program won't call several functions at once. Let me know if you have any questions.
def recursive_main_function():
# Infinitely loops unless user presses 'q'
while(True):
# Waits for the question's input
user_question1 = input("Select one of the following four options:\n s see the sample rate of the file\n c change the playback speed\n m mix two signals together\n f filter the signal or\n q quit \n : ")
# Respond based on input provided
if user_question1 == "s":
s_function()
elif user_question1 == "c":
c_function()
elif user_question1 == "m":
m_function()
elif user_question1 == "f":
f_function()
elif user_question1 == "q":
# Breaks the user out of the while loop
break
else:
print("Invalid response. Please try again" + user_question1)
# End of function, exits script
return
# To initiate script
recursive_main_function()
This is a shorter version of my answer to a related question.
Rather than a forest of ifs, you could use a dictionary to match user input to a function.
def c_function(argv):
print("you have successfully called c_function")# These print statements are just place holders for the actual functions
return 0
def m_function(argv):
print("you have successfully called m_function")
return 0
def f_function(argv):
print("you have successfully called f_function")
return 0
def s_function(argv):
print("you have successfully called s_function")
return 0
def help_function(argv):
print('available commands:')
print(' s see the sample rate of the file')
print(' c change the playback speed')
print(' m mix two signals together')
print(' f filter the signal')
print(' help print the list of commands')
print(' quit quit')
return 0
def quit_function(argv):
env['didntQuit'] = False
return 0
def notfound_function(argv):
print('{}: {}: command not found'.format(env['replname'], argv[0]))
return -1
def print_return_value(ret, argv):
if ret != 0:
print('{}: command {} failed with return value {}'.format(env['replname'], argv[0], ret))
env = { 'replname': 'wav-processor-repl', 'prompt': '$ ', 'didntQuit': True }
command_dict = {'c': c_function, 'm': m_function, 'f': f_function, 'h': help_function, 'help': help_function, 'q': quit_function, 'quit': quit_function}
while env['didntQuit']:
argv = input(env['prompt']).strip().split() # read
command = command_dict.get(argv[0], notfound_function) # identify command
ret = command(argv) # execute command
print_return_value(ret, argv) # error message if command failed
Output:
$ c
you have successfully called c_function
$ f
you have successfully called f_function
$ g
waf-processor-repl: g: command not found
waf-processor-repl: command g failed with return value -1
$ f
you have successfully called f_function
$ h
available commands:
s see the sample rate of the file
c change the playback speed
m mix two signals together
f filter the signal
help print the list of commands
quit quit
$ m
you have successfully called m_function
$ q
I have a menu for booking reservations and it writes a reservation list and seating chart to text files every time someone enters a new reservation.
I have a menu that has the option to display the seating chart, purchase a seat, a nested admin menu, or quit. the admin command opens a new menu that lets you clear the contents of the reservation list, return to the main menu, or quit; or at least it is supposed to. I must have something wrong with the error checking, or maybe I cannot build it this way. Can someone see where i am going wrong? I have a large program and can post more, but would rather just post the portions i am having trouble with. the other functions are defined at the main program level(same level as the menu function), should the nested functions also be defined at that level? thanks.
def menu():
print(
'Select chioce from menu:\n\nP to purchase an available bus seat\nD to display current bus seat chart\nEnter password (admin) for admin menu\nQ to quit')
while True:
try:
menu_choice = str(input(' \n')).upper()
if menu_choice == str('D'):
display()
break
elif menu_choice == str('P'):
book()
break
elif menu_choice == str('ADMIN'):
def clear_booking(): # the nested functions are not working-
print('Clearing bookings')
with open("bookings.txt") as f:
f.write("")
def previous():
menu()
print('CB to clear bookings\nR to return to main menu\nQ to quit')
admin_choice = str(input(' \n')).upper
if admin_choice == str('CB'):
clear_booking()
elif admin_choice == str('R'):
previous()
elif admin_choice == str('Q'):
exit()
else:
print('Invalid choice')
exit()
elif menu_choice == str('Q'):
print('exiting program')
exit()
else:
print('Value not recognized.')
exit()
except ValueError:
print('Invalid entry')
return # how do i get rid of the none from this returning correctly?
print(menu())
You forgot the () at the admin_choice = str(input(' \n')).upper at the upper() function call.
Also maybe you can return a string with text instead of just return at the last line of your menu() function body
Also try to include your problem statement in the introductory text of your question to make it clear what the problem is with your code, and what you want to achieve.
I am making a text-based game on python using the class system to keep track of main character changes (like its name). I am writing the main code for the game outside of the Main Character Class- inside of the main function.
I am struggling because I need to update self.character_name inside the Main Character class to an input from the user inside the main function. I am unsure how to do this, I have the code written below- however it is not updating the name inside Main Character class. How can I rewrite this?
I'm also worried that I will have this problem when trying to update pets, characters_known. However, I do not seem to have this problem with updating Health or XP....
class Main_Character():
def __init__(self):
self.health=100
self.exp=0
self.level=0
self.character_name=""
self.characters_known={None}
self.pets={None}
self.progression_tracker=0
def __str__(self):
return "Name: "+ str(self.character_name)+" | "+ "Health:"+ str(self.health) + " | " +"XP:"+ str(self.exp) + " | "+ "Level:"+ str(self.level)+" | "+"Pets:"+str(self.pets)
def Char_Name(self,name):
if name.isalpha()==False:
print("You entered a name containing non-alphabetic characters, pease reenter a new name:")
main()
elif len(name)>=10:
print("You entered a name containing 10 or more characters, pease reenter a new name:")
main()
else:
self.character_name=name
def Char_Level_Experience(self,exp,b):
self.exp+=exp
b=2
if exp<=0:
exp=1
ans = 1
level=0
while ans<exp:
ans *= b
level += 1
if ans == exp:
self.level=level
print("You have reached level", self.level)
else:
level = int(log(exp, 2))
level = min(level, exp)
if level>=0:
self.level=level
else:
level=0
def healing(self,heal):
if self.health+heal>=100:
self.health=100
else:
self.health+=heal
def other_answers(answer):
if answer=='quit':
raise SystemExit
if answer=='pets':
print("Pets owned:", Main_Character().pets)
user_decision=input("Would you like to continue where you left off? Type 'yes' to continue, or 'no' to go back to main menu")
if user_decision=='yes':
if Main_Character().progression_tracker==0:
main()
elif Main_Character().progression_tracker==1:
choice1()
if user_decision=='no':
main()
else:
other_answers(user_decision)
if answer=='characters':
print("Characters met:", Main_Character().characters_known)
user_decision=input("Would you like to continue where you left off? Type 'yes' to continue, or 'no' to go back to main menu:")
if user_decision=='yes':
if Main_Character().progression_tracker==0:
main()
if Main_Character().progression_tracker==1:
choice1()
if user_decision=='no':
main()
else:
other_answers(user_decision)
def start_check():
print("If you understand the game, type 'go' to continue- if not, type 'more information' to receive more information about how to play the game")
begin_game=input("")
if begin_game=="go":
choice1()
if begin_game=='more information':
print("\n","The object of the game is to gain XP [experience points] without dying")
start_check()
else:
other_answers(begin_game)
def choice1():
Main_Character().progression_tracker=1
print("You are a knight in the Kings Guard- the King has asked to meet with you about a very special mission")
print("What would you like to do?")
print(" 1.Go Directly to King","\n", "2. Finish your dinner")
choice=input("1 or 2?")
if choice=="1":
Main_Character().Char_Level_Experience(1,2)
elif choice=="2":
Main_Character().Char_Level_Experience(.5,2)
else:
other_answers(choice)
print(Main_Character())
def main():
print("Welcome!")
unfiltered_name=input("Please enter the name of your character:")
Main_Character().Char_Name(unfiltered_name)
print("Welcome,", Main_Character().character_name,"!", "Here are your current stats!")
print(Main_Character())
start_check()
You haven't quite understood how classes and instances work.
Calling the class is what you do when you need a new character. Every time you call Main_Character(), you get a whole new instance - with the default values as set in __init__. If you had characters for each of your friends, you would call it one time for each one. You then would need to keep each of those instances in a variable, so you can reference them again each time.
So, for instance:
my_character = Main_Character()
unfiltered_name=input("Please enter the name of your character:")
my_character.Char_Name(unfiltered_name)
print("Welcome,", my_character.character_name,"!", "Here are your current stats!")
print(my_character)
You create a new character each time you call Main_Character. Instead, you should call it once:
the_character = Main_Character()
...
the_character.name = "..."
Newish to python, working on a text adventure, testing out the use of functions.
def cell1():
loop = 1
while loop == 1:
print("ONE")
cave1 = input()
if cave1 == ("end?"):
print("\nthis should end program")
loop = 0
break
elif cave1 == ("TWO"):
global testvar
testvar = 1
option1()
else:
print("INVALID")
def option1():
print("TWO")
loop = 1
while loop == 1:
print("test1 definition")
print (testvar)
test1 = input()
if test1 == ("ONE"):
print("you pick up the cheese")
loop = 0
cell1()
elif test1 == ("THREE"):
option2()
else:
print("INVALID")
def option2():
print("THREE")
loop = 1
while loop == 1:
print("This is option 3")
test2 = input()
if test2 == ("ONE"):
print("testering2")
cell1()
elif test2 == ("TWO"):
global testvar
testvar = 2014
option1()
else:
print("INVALID")
run = True
while run == (True):
print ("testing 123")
cell1()
print("restart about to activate")
cont = input("Restart? ")
if (cont) != "yes":
break
This program should allow you to go between options (what would be rooms) and eventually in cell1, the program should be end-able.
if the program is run and "end?" is typed as the first input, the program goes into the continue bit at the bottom, however, if you go between the 'rooms' then back to cell1, typing "end?" will call option 2.
Ive had a look around and it is still baffling me, am i ding something wrong?
Any help is appreciated, thank you.
The reason "end?" only quits for the player when they are within the first cell is because you're only checking for that input therein. The execution contained within option1() and option2() doesn't affect the execution of cell1(). You're not returning anything from your option functions, nor are you changing a sentinel value.
So, there's two basic ways you could go about this.
First, you could return a value from your functions:
if option1() == "END":
break
Or, you could alter your while loop:
# is_running is defined globally
while is_running:
And then just set is_running to False in any of your methods whenever the user types "end?". That'd probably be the easiest way with the design you're using now.
I'm sure you can tell, though, that in general your program is going to get exponentially more complex as you add more rooms and your function calls get further nested.
I'm pretty sure that the issue you're having is because you don't always break out of the loop in one function when you call another function. For instance, if your entries were TWO, ONE then end?, you'd find yourself still in the cell1 loop. That's because when the inner call to cell1 returns, the control flow of the program goes back to where that function was called from, which is option1, since loop is now 0, the loop ends and option1 returns, to the outer call to cell1, where the loop is still running.
Unless you want the game you're designing to have a tree structure, where you can return to where you came from with different semantics than moving to some other place, I'd suggest using a different architecture. Rather than each of your functions calling the next function when appropriate, return that function instead. Then you'd write a single top level loop that calls the function. Here's an example where the function to be called by the top level loop is saved in a variable named state:
def cell1():
print("In cell1!")
while True:
choice = input("pick 'ONE' or 'TWO' (or type 'quit' to exit):")
if choice == "ONE":
return option1
elif choice == "TWO":
return option2
elif choice == "quit":
return None
else:
print("I'm sorry, I didn't understand that.")
def option1(): # these other two functions are very basic in my example
print("In option1!") # but you can make them as complex as you want
return option2
def option2():
print("in option2!")
return cell1
def control_loop(initial_state=cell1):
state = initial_state
while state is not None:
state = state() # the next state is the return value of the previous state
The problem is you are getting deeper and deeper within nested functions. For example, changing
if test1 == ("ONE"):
print("you pick up the cheese")
loop = 0
cell1()
to
if test1 == ("ONE"):
print("you pick up the cheese")
loop = 0
break
will allow you to run your program, enter room two, go back to room one, and "end?" will work properly. This won't fix your issues completely though because there is a similar problem where when you go from two to three where if you simply changed
if test2 == ("ONE"):
print("testering2")
cell1()
to
if test2 == ("ONE"):
print("testering2")
break
it would break the current function and go back into option1() (if you run your program, go to room two, then to room three, then back to one) where "end?" doesn't do anything. Hopefully this gets you on the right track.
I have written another simple program that I call my basic 'Python Calculator.' So far, I have found a problem with some of the code that I have written in Python 3.3.2. Here is the code below so you can read it before I state my problem...
def startup_screen():
user_input_1 = int(input("Please enter your first number.\n"))
user_input_2 = int(input("Now please enter your second number.\n"))
command_list()
def command_list():
user_command = input("Now what would you like to do with these two numbers?\n").lower()
if user_command == "add":
calc_add()
elif user_command == "subtract":
calc_subtract()
elif user_command == "multiply":
calc_multiply()
elif user_command == "divide":
calc_divide
else:
print("Please try again.")
user_command
def calc_add():
add_result = (user_input_1+user_input_2)
print(add_result)
command_list()
def calc_subtract():
subtract_result = (user_input_1-user_input_2)
print(subtract_result)
command_list()
def calc_multiply():
multiply_result = (user_input_1*user_input_2)
print(multiply_result)
command_list()
def calc_divide():
divide_result = (user_input_1/user_input_2)
print(divide_result)
command_list()
startup_screen()
Here, you can see that I have defined the startup_screen, which collects user input as an integer and then stores it respectively in user_1 and user_2. Then, the user is taken to the command home screen where they can choose to either add, subtract, multiply or divide both numbers. The command is then determined from the user input, so if the user wants to add two numbers, they type in 'add' and they are taken to the add function - as defined above.
However, in the add function, the user_1 and user_2 inputs are not recognized, as well as in the other programs... so it causes an error in the in the program. I have no idea what to do. Could you please help me?
Thank you very much...
Lets look at you program from the point of view of the def calc_add(): function.
In the first line,
add_result = (user_input_1 + user_input_2)
you say, take the value of user_input_1 add it to user_input_2 and make that into the variable add_result. Okay that makes sense.
Now lets get the first value user_input_1... lets see, first place to check is the 'local scope'. That is the function i am currently in.
def calc_add():
add_result = (user_input_1 + user_input_2)
print(add_result)
Okay nope, nothing there... okay maybe it was one of the input parameters ?
def calc_add():
Nope no input parameters were passed to this function. Okay it must be global ... but wait crap... no global parameters are ever decalred! especially not user_input_1. Well dang it, im supposed to add two parameters but one of the parameters doesnt exist! Thats not possible I better throw an error!
Maybe if the programmer had passed me the information i needed it would work better,
Maybe something like this :
def load_screen():
user_1 = int(input("Please enter your first number.\n"))
user_2 = int(input("Now please enter your second number.\n"))
command_home( user_1, user_2) # Okay command_home I took 2 inputs!
# Here they are work your magic!
def command_home(in1, in2): # Hey I need 2 varaibles to work, Ill call them in1 and in2.
# so based on the way command_home( user_1, user_2) is called
# in1 = user_1, in2 = user_2
command = input("Now what would you like to do with these two numbers?\n").lower()
if command == "add":
calc_add(in1, in2) #Okay, now i need to add my two inputs,
# but calc_add is another function it wont be able to see MY
# in1, in2 ... i better pass them over as parameters.
elif command == "subtract":
calc_subtract()
elif command == "multiply":
calc_multiply()
elif command == "divide":
calc_divide()
def calc_add(user_input_1,user_input_2 ): # Okay now i know where to look for user_input_1
# and user_input_2, they will be passed to me
# when someone calls me! Now i can find my varables
# and i wont throw an error!
add_result = (user_input_1 + user_input_2)
print(add_result)
Give the inputs as arguments to the functions that follow, the values are not global variables (not immediately accessible by any function) if they are defined within a function.
def loadscreen():
...
command_home(user_input_1,user_input_2)
def command_home(user_input_1,user_input_2):
...
calc_add(user_input_1,user_input_2)
def calc_add(user_input_1,user_input_2)
add_result = (user_input_1 + user_input_2)
print(add_result)
You are not passing the user's input into the later functions which rely on it, such as calc_add().
The way to fix this problems would be to modify your code like so:
def startup_screen():
user_1 = int(input("Please enter your first number.\n"))
user_2 = int(input("Now please enter your second number.\n"))
command_home(user_1,user_2)
def command_home(u1,u2):
command = input("Now what would you like to do with these two numbers?\n").lower()
if command == "add":
calc_add(u1,u2)
elif command == "subtract":
calc_subtract(u1,u2)
elif command == "multiply":
calc_multiply(u1,u2)
elif command == "divide":
calc_divide(u1,u2)
def calc_add(user_input_1,user_input_2):
add_result = (user_input_1 + user_input_2)
print(add_result)
"""the rest of the functions go here, must be defined to take the inputs passed"""
startup_screen()
We have redefined command_home to take two objects as inputs (which should be the user_1 and user_2 from load_screen). You could call them anything but I called them u1 and u2 so I wouldn't have to type so much. Now, command_home has these values and can, in turn, pass them into the functions which it calls that need them. We have also changed all of the function calls inside the if/elif block so that u1 and u2 are passed into those functions.
Then, we have redifined calc_add to take two inputs, and I called them the same as you did already inside the function, so I would have one less line to change - user_input_1 and user_input_2.
Now when you ask for them to be added together into add_result, they exist and have the expected values, so everything now works.