Function called without being told to - python

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.

Related

How do I get my code to run the if statement?

I'm a beginner in Python and I'm writing a code for a school project and ran into an early bug.
For some reason my if function won't run.
import time #imports computer time to program(buit in function)
count= 0
print(" Gymship") # center this
print("--------------------------------------") # this should go across the whole screen
print("Input a level to view the description or InputSign up to begin signing up for a card")
print("--------------------------------------------------------------------------")
print("Bronze")
time.sleep(1) # this wil pause the program for 1 second(for effect)
print("Silver")
time.sleep(1)
print("Gold")
time.sleep(1)
print("Platinum")
time.sleep(2)
print("-----------------------------------------------") # this should go across the whole screen
print("Sign up")
print(" ")
input()
if input == "Bronze":
print("Bronze")
print("--------------------------------------------")
print("You acquire a bronze card when you use two or less gym services")
print("2 Hours limit in the gym")
print("-------------------------------------")
print(input("Back to return to menu screen"))
count = count + 1
This is not correct:
input()
if input == "Bronze":
The way input() works is by returning a value. The name input refers to the function itself, so the function input will never equal the text "Bronze" unless you explicitly do something bad, like input = "Bronze" (it's bad because if you overwrite input, you'll no longer be able to access that function).
Instead, you should be using the returned value:
usr_input = input()
if usr_input == "Bronze":
Also, the line print(input("Back to return to menu screen")) is unnecessarily complicated; the print() will print whatever was returned by input(), but input() will display the "Back to return to menu screen" prompt without wrapping it in an if statement. So, input("Back to return to menu screen") is all you need. If you keep it the way you have it, if someone typed some text and then hit enter, the text would display again, because the print() is printing whatever that text was that the user typed.
You first need to assign a variable to the input and then check if the variable is equal to "Bronze"
Right now you are taking the input, but are not storing it anywhere. So the fixed code would be
user_input = input()
if user_input == "Bronze":

Why does my function do what its supposed to do then it does not continue through the code?

I am making a choose your own adventure game and I have a function to check if what you input in the console is acceptable or not. In the beginning, you can only type "turn on light" if you type anything else it will return as an error and you will be prompted to type an actual action. The problem I have is after you type something that isn't accepted it will not let you continue after you make an error.
actions = ['help','turn light on',]
def errorcheck(player_input):
if player_input in actions:
error = False
return()
else:
error = True
while error == True:
print('i dont know what you mean by',player_input)
player_input = input('>')
if player_input in actions:
error = False
else:
error = True
print('welcome to TITLE')
print('type help at anytime to see your options')
print('">" that symbol promts you to do something')
print('')
print('you wake up, its dark')
player_input = input('>')
errorcheck(player_input)
if error == False:
if player_input == ('help'):
playerhelp = True
while playerhelp == True:
print('you can: turn light on')
playerhelp = False
errorcheck potentially modifies player_input that it accepts as an argument. It is a new local variable that has nothing to do with the global player_input.
A naive solution would be to make player_input a global variable, but that would be a bad, anti-pattern solution for several reasons:
global variables tend to lead to messy, hard to debug code
a function should preferably do one thing, and that thing should preferably be what its name suggests it does.
Instead, have errorcheck only check the input as its name suggests.
def errorcheck(player_input):
return player_input not in actions
player_input = None
while errorcheck(player_input):
player_input = input('>')
At this point having errorcheck as a function seems a bit superfluous. You do not really need it:
player_input = None
while player_input not in actions:
player_input = input('>')
First of all you should definitely never use a local variable from a function in your main code. If you want to access error you should return it as such:
def errorcheck(player_input):
if player_input in actions:
error = False
else:
error = True
while error == True:
print('i dont know what you mean by',player_input)
player_input = input('>')
if player_input in actions:
error = False
else:
error = True
return error
Secondly it is no wonder that your program stops after entering help since after that there is no more code. If you want the user to be continuously be required to enter something you must put a loop around the whole parsing logic...

Infinite Loop occurs when using main function

Was playing with loops to prepare for my incoming project. and I found infinite loop when using while loop + main function
#1
def choice(name):
while True:
if name == "Eat"
print("I don't want to eat now")
elif name == "Drink"
print("NOPE")
else:
print("o.O?")
def main():
name = input("Eat or Drink ? :")
choice(name)
main()
#2
while True:
name = input("Eat or Drink ? :")
if name == "Eat"
print("I don't want to eat now")
elif name == "Drink"
print("NOPE")
else:
print("o.O?")
Number 2 doesn't generate infinite loops despite I don't have any return
But when I use Number 1, so that I can use the name variable into different functions in future, it generates infinite loop.
Can I know the reason why it is happening? and how do I fix it while keeping name variable nested in main function?
Thanks!
It's because in version #2 you read input from console on every loop iteration (this line: name = input("Eat or Drink ? :")). So it is still an infinite loop, but this time it waits on every iteration until you provide some input.
You can fix it by just adding this line: name = input("Eat or Drink ? :") to your choice function or use:
for i in range(100):
...
If you want to limit the number of iterations.
EDIT:
Ok, so take while True from choice function and put it into main, like this:
def main():
while True:
name = input("Eat or Drink ? :")
choice(name)
... other functions using name

Python 3.4.2:My infinite function while loop is not working

My infinite while loop is not working as I expected it:
def main():
print("Type 1 to create a file")
print("Type 2 to read a file")
print("Type 3 to append a file")
print("Type 4 to calculate total of file")
print("Type 5 to end the program")
choice=input("Select a number:")
if choice == '1':
file_create(filename)
elif choice == '2':
read_file(filename)
elif choice == '3':
append_file(filename)
elif choice == '4':
add_numbers(filename)
filename=input("Give a name to your file:")
while main():
# ...
This executes the main once, but it does not loop.
Mr.Anyoneoutthere, Sylvain is absolutely correct. Since you don't understand it, I'll explain.
A loop needs a conditon:- True OR False.
So when you say:-
while True:
print('World')
is the same as:-
a = 100
while a == 100:
print('poop')
Since a == 100 would evaluate to 'True', and start a loop because you let the value remain constant, and start an infinite loop. But you can directly put the evaluation, i.e., 'True', so as to directly start an infinite loop.
As you have put:-
while main():
print('World')
So now think... while main()... main() what?... the compiler does not get any code to evaluate something into 'True' or 'False' and the loop never starts!
So your required correct code is:-
while True:
main()
def main():
# ...
# <- no return statement
while main():
# Something
The while loop loops as long as the condition is true. Here, as your main() function does not have a return statement, it doesn't return anything explicitly. So Python behave as if it were returning None. None is not true. So the condition is false and you don't execute the body even once.
What about something like that (assuming you need to execute main() until the user wants to quit):
def main():
# ...
print("Type 9 to quit")
choice=input("Select a number:")
if choice == '9':
return False
# Handle other cases
if choice == '1':
file_create(filename)
elif choice == '2':
# ...
return True
On the other hand, as suggested by #thiruvenkadam in a comment below, you could keep your main as it was written in your question, but really write an infinite loop:
while True:
main()
But that way, if you want to terminate your program gracefully , you will have to rely on some other mechanism like using exceptions...

How to return to beginning of loop?

search_room = raw_input("Search the:")
if search_room == "classroom":
print "You quitly make your way to the classroom, which is empty besides last night's homework"
sleep(3)
print "Enter 'inspect' into the command line to inspect the homework, or enter exit, to return to the kitchen."
action = raw_input("Command:")
if action == "inspect":
print "Hmph, uncompleted. Thats strange."
print "Enter 'inspect' into the command line to inspect the homework, or enter exit, to return to the kitchen."
action = raw_input("Command:")
if action == "exit":
print "you return to the kitchen"
search_room = raw_input("Search the:")
if action == "classroom":
I'm trying to figure out how to have this loop so i one could travel back and forth between the kitchen and the classroom, but if I try to go back to the classroom after exiting, I get an error message regarding a later 'for loop'.
If I understand your question correctly, your trying to figure out how to set up a loop that will let you go from kitchen back to classroom and so on and so forth without needing to nest an infinite amount of conditionals. I suggest you have an outer while(true) loop power the sequence of steps, and add conditions to check if a move is valid (to go to to the kitchen you must currently be in the classroom and have entered exit, ect)
You need to put the code block inside its own loop with a simple boolean sentinel value (while not stop) and if stop is set to true at any point, the otherwise endless loop will stop. Also remember the importance of python indentations for distinguishing code scopes, different from languages like java where it doesn't matter where you put the code as long as it is between the { }. Also consecutive if statements will each be executed individually unless you use if..elif which is what I think you want because you are comparing the same variable in the same scope.
Also if you have more than two rooms, like something in the game Clue, you should define some sort of scoping for each room. If you are in a room, which rooms can you access from there? I did this just with a simple dictionary scopes where each room is associated with a list of rooms it can access which is verified on getting search_room. They only have access to each other right now, but you can add more to each list to increase scope to other rooms (and add more if branches)
stop = false;
scopes = {"kitchen": ["classroom"], "classroom": ["kitchen"]}
locCur = "kitchen" #starting room
locPrev = "kitchen"
while not stop:
search_room = raw_input("Search the:")
if scopes[locCur].index(search_room) > -1 : #validate the room choice
if search_room == "classroom":
locCur = "classroom" #update current scope
print "You quietly make your way to the classroom, which is empty besides last night's homework"
sleep(3)
print "Enter 'inspect' into the command line to inspect the homework, or enter exit, to return to the kitchen."
action = raw_input("Command:")
if action == "inspect":
print "Hmph, uncompleted. Thats strange."
print "Enter 'inspect' into the command line to inspect the homework, or enter exit, to return to the kitchen."
action = raw_input("Command:")
if action == "inspect":
#print/do something else
elif action == "exit":
locCur = locPrev #set scope back to what it was
print "you return to the " + locPrev
locPrev = "classroom" #store this location
continue
elif search_room == "kitchen":
#do something for this room
print "message"
continue
elif search_room == "some other room":
#do something for this room
continue
elif search_room == "stop":
stop = true

Categories