only letting user do a function once in Python? - python

I am very new to Python. running on windows while I wait for some stuff for my Pi.
I am writing a game where the user travels through a tower via text inputs.
the user can use "a" "d" "w" to look around a room to collect sutff. but if the user has already looked in "a" (which is "look left") i need to let them know they have already been there.
this is my code but it has an obvious flaw.
#if user hits 'a' they look left
def roomOneLeft():
print '-- You search some loose rubble and find some cloth'
return roomOneMoves()
#where the user selects a movement
def roomOneMoves():
left = 0
move = raw_input("")
if left == 1:
print 'you have already looked here'
return roomOneMoves()
if move == "a":
left = left + 1
roomOneLeft()
can i set "left" to static? and ant work out how to set it as global variable like java. this obviously doesn't work because when it returns, it sets itself back to 0. any help would be greatly appreciated!

You can define "left" as global. Like this:
left = 0
#where the user selects a movement
def roomOneMoves():
global left
move = raw_input("")
if left == 1:
print 'you have already looked here'
return roomOneMoves()
if move == "a":
left = left + 1
roomOneLeft()

To make a variable global, declare in the module scope, and then to change it in a function, use the global keyword.
left = 0
def some_func()
global left
left = 1
That will allow you to edit global variables inside a function.
To address your static variable question, I believe you cannot do this in python. See this question.

Related

Can variables retain previous values in a while loop in python? [duplicate]

This question already has answers here:
How do I clone a list so that it doesn't change unexpectedly after assignment?
(24 answers)
Closed 6 years ago.
My question is when we use a variable in a while loop before changing the variable we have it assigned to (i.e on the Right hand side of the equal to) why does this new variable we supposedly assigned the next variables previous value to change?
I realise the phrasing of my question isn't entirely spot on, so in laymans terms, in my program i'm writing a variable called predispto disp before I change the value of displater in the while loop. Here i'm assuming all the code in python runs from top to bottom.
So here's an example of what value predisp holds
so if disp = ['_','_']
predisp = ['_','_']
which is fine.
But the moment I enter a letter as part of my hangman guess
the value of disp becomes ['u','_']
but the problem is predisp also becomes ['u','_'] which is not what I want. I want it to always have the previous value of disp before it undergoes any changes. I'm new to python so I don't really understand how all the variables work, i'm more used to them in C++. Here's the code (it's for a simple hangman game i'm writing).
# Created by Zur-en-Arrh
import random # Useful to select a topic from the file.
# Functions
def same_letter(user_letter, word_to_guess):
if user_letter == word_to_guess:
return True
else:
return False
def wrong_guess(prevdisp,currdisp):
if prevdisp == currdisp:
return True
else:
return False
# Dealing with the file.
filename = input("Which file do you want to play with ")
topics = str(open(filename, 'r').read())
list_of_topics = topics.split() # This is the list that contains the topics randomly selected from the file.
guess_me = list(list_of_topics[random.randint(0, len(list_of_topics) - 1)]) # This is what the user will need to figure out.
# Printing out the Dashes for the user.
disp = []
for i in range(0, len(guess_me)):
disp.append("_")
# This is just the declaration of the number of wrong guesses. This'll always be 0 at the start of the game.
wrong_guesses = 0
# While loop for game. Also note in hangman, you're only allowed 5 wrong guesses till the body is complete.
while wrong_guesses < 6:
print(' '.join(disp)) # Prints the game in an acceptable format to the user.
predisp = disp
if disp == guess_me: # end the game when the user wins.
break
user_guess = str(input("Which letter do you think will there be? "))
for i in range(len(guess_me)):
if same_letter(user_guess, guess_me[i]):
disp[i] = user_guess
print(predisp)
if wrong_guess(predisp, disp):
wrong_guesses += 1
if wrong_guesses == 6:
print("You got hung! Better luck next time")
break
if wrong_guesses < 6:
print("Well Done you won the game!")
In Python, variables are references to objects:
disp = []
creates a new list object and makes it accessible by the name disp. What it really does is set disp to point to the newly created list object. The assignment statement
predisp = disp
does the same thing, i.e. it sets predisp to reference the same list object as disp. Thus any change applied to the object that disp points to is also visible in the object that predisp points to - it's the very same object.
One way to avoid this is to create a copy on assignment:
predisp = disp[:]
This can be easily verified by using the id function:
disp = ['_'] * 3
predisp = disp
id(disp), id(predisp)
# same object ids for both variables
=> (4303250784, 4303250784)
predisp = disp[:]
id(disp), id(predisp)
# different object ids
=> (4303250784, 4303043832)

Python Turtle: I want to make a function that executes another function depending on what the previously executed function was

I'm drawing my name using turtles and I have a bunch of different functions for each of the letters
like so (for letter r)
def letter_r(t):
def letter_r_top(t):
turtle.lt(90)
turtle.fd(150)
turtle.rt(90)
turtle.circle(-37.5,180)
turtle.lt(130)
def letter_r_leg(t):
csquare = ((75**2) + (37.5**2))
sidec = math.sqrt(csquare)
turtle.fd(sidec)
letter_r_top(rob)
letter_r_leg(rob)
After each letter, i need to move the turtle into the right place to setup for the next letter. Because each of the letters are different sizes I need to make custom movements depending on what the previous letter is but I dont want to make separate functions for each of those movements.
At the end of my code I have the list of functions to be called in the correct order to spell my name
letter_t(rob)
letter_setup(rob)
letter_r(rob)
letter_setup(rob)
.....
Is there a way that I can do something like this so that I will only need 1 setup function.(Not real code, just a conceptualization of what I'm thinking
def letter_setup(t):
if previously executed function A
turtle.fd(75)
if previously executed function B
turtle.fd(75)
turtle.lt(90)
if previously executed function C
turtle.fd(75)
turtle.lt(90)
Why not the movement to the right place for the next letter at the end of the previous letter?
Perhaps there is a better way to do this but you could make a variable last_function_called and in each function you give it a different value then you'll know wich one was the last called :
last_function_called = NONE;
def function1():
last_function_called = FUNCTION1
blablabla
...
if (last_function_called == FUNCTION1):
call another one
and before of course something like :
NONE = 0
FUNCTION1 = 1
FUNCTION2 = 2
ect...

Python 3.4.2 | NameError: name 'x' is not defined

I'm working on a word based maze game in Python 3.4.2, and I am having problems with this error message when I try to run it: NameError: name 'direction' is not defined
This is how I have defined it:
def chooseDirection():
direction = input('''What way will you go? (Type Left or Right or Forward then press enter.) ''')
Then I tried using 'direction' this way:
if direction == str(Right or right):
print ('Congrats! You have turned the right way, you can live...')
time.sleep(1)
print ('For now o.O')
I can't find any issues with my code, and I have checked some other similar questions from stackoverflow, but none have worked.
Here is my full code
Any idea's would be greatly appreciated and let me know if you need any more information.
Thanks, Sebastian.
def checkDirection(chooseDirection):
print('You have now entered the maze.')
time.sleep(0.5)
if direction == str(Right or right):
print ('Congrats! You have turned the right way, you can live...')
time.sleep(1)
print ('For now o.O')
replace direction with chooseDirection because that is the argument you are trying to pass ( or take the value)
for if else if you use
if (direction == 'Right' or direction == 'Left'):
Also
def chooseDirection():
direction = input('''What way will you go? (Type Left or Right or Forward then press enter.) ''')
return chooseDirection
I think you want to return direction, not chooseDirection.
I checked your code. You really need to read a good tutorial on Python.
For correction your code;
First of all you should change checkDirection parameter to direction. You do not have direction variable in checkDirection method.
def checkDirection(direction):
...
Also you do not handle return value of chooseDirection method.
Inside while loop you should put it a variable and call checkDirection with it
d = chooseDirection()
checkDirection(d)
Finally chooseDirection not return correct variable. It should be direction

Trying to return a True variable from a nested chain of functions (in Python)...

I'm trying to write part of an adventure game program in Python, and though I have most of it down, I'm stuck at trying to return a value declared as "True" at the end of one branch in the function chain. Basically, this is a fight against a monster, which you can win if you choose the right options. If you win, you obtain the bow that he was guarding. Here is the code of the fight:
#The first line imports all the text displayed in the game, saved in gametext.py
#For purposes of clarity, all text has been saved to variables imported by the file.
#Any variable that is not "HaveBow", "why" or declared by a raw_input() is actually text.
from gametext import *
def BG_fight():
print BowGuardIntro
print InitOptions
BGfirstmove = raw_input('> ')
if BGfirstmove == "1":
spearfight()
elif BGfirstmove == "2":
dead(BGUnarmed1)
else:
dead(BGUnarmed2)
def spearfight():
print GotSpear
print SpearFight
spearact = raw_input("> ")
if spearact == "1":
blindfight()
elif spearact == "2":
dead(SeeChest)
elif spearact == "3":
dead(SeeArms)
else:
dead(NoUseSpear)
def blindfight():
print BlindFight
followblow = raw_input("> ")
if followblow == "1":
print Victory
HaveBow = True
return HaveBow
elif followblow == "2":
dead(BlindArms)
else:
dead(BlindNoKill)
def dead(why):
print why
exit(0)
BG_fight()
(If people are interested, I can also produce the contents of the gametext file, though I would rather not as it is lengthy and has nothing to do with the problem I'm having)
As you can see, only one branch there offers the winning condition (which would give the HaveBow = True value that I want to return), and it is nested two functions deep and part of an if-statement. What I want to know is how I return that "HaveBow = True" value back outside the function chain, so it can be used in other parts of the game? If I try to code:
HaveBow = blindfight()
print HaveBow
at the end of the code and try to run it, it just makes me repeat that part of the game twice, before declaring "True". Same goes if I try BG_fight() instead of blindfight(). But I don't want that; I just want the "True" for "HaveBow" so I can use the condition "HaveBow = True" in other parts of the game.
In short, my question is whether or not it's possible to return a value from a nested function chain without repeating the code of that chain, and if so, how?
Thanks.
You can only return a value, not a name and a value. In other words, you cannot "return HaveBow = True"; all you can do is return True. There's no way to return a value and at the same time assign it to a variable that exists outside the function. If you want to assign the value, you need to do it outside the function.
From what you say, it sounds like you want HaveBow to be a global variable that you can use anywhere in your program. In that case, you can change your code in blindfight to do:
if followblow == "1":
global HaveBow
print Victory
HaveBow = True
Note that in this case you do not need to return the True value -- you just directly assign it to a global variable.
Ultimately there are better ways to structure your code, but those issues are out of the scope of this question. For the moment, I would suggest that, if you have global state like HaveBow that you want to be able to use "anywhere else in the game", you should make those global variables using global as I showed in my example. As you progress learning more programming, you will gradually learn why using global variables is not usually the best idea, but for the purposes of this program it is the simplest solution.

Any reason why my Python code is not showing up?

I am learning how to code in Python and using the IDLE, I have put in this code, however when I hit F5, nothing happens... no output occurs.
Is this due to maybe the fact that the code I have put in doesn't need an output? Or maybe I am saving it wrongly. Would love to know the reason as it is slightly upsetting.
X = "X" #This is to indicate one piece of the game
O = "O" #this is to indicate another piece of the game
EMPTY = "" # an empty square on the board.
TIE = "TIE" #represents a tie game
NUM_SQUARES = "9" #number of squares on the board
def display_instruct(): #this is a function with the name display_instruct.
"""display game instructions."""
print \
""" Welcome to the greatest challenge of all time: Tic-tac toe. This would be a showdown betweene your human brain
and my silcon processor You will mkae your move known by entering a number
0 | 1 | 2
---------
3 | 4 | 5
---------
6 | 7 |8
Prepare yourself, human. The ultimate battle is about to begin. \n """
def ask_yes__no(question):
"""Ask a yes or no question"""
response = None
while response not in ("y", "n"):
response = raw_input(question).lower()
return response
#this produces a function. It receives a question and thenn responds with an answer which is either yes or not
def ask_number(question, low, high):
"""Ask for a number within the range"""
response = None
while response not in range(low, high):
response - int(raw_input(question))
return response
#remember that when defining the functions, you have to put in colons. The user recieves a question and then has to give an answer.
def pieces():
"""Determine if player or computer goes first""" #docstrings are used to name the functions.
go_first = ask_yes_no("Do you requre the first move?y/n: ")
if go_first == "y": #important to have two equal signs because you are giving a variable a name. Notice that one function callled another.
print "\n Then take the first move, you will need it."
human = X
computer = 0
else:
print "\n Your bravery will beyour undoing .... I will go first."
computer = X
human = O
return computer, human
You need to define and call a main function
def main():
display_instruct()
#the rest of the code
if __name__ == "__main__":
main()
The reason your code doesn't run is because what you have is function definitions
def func() ...
and value assignments
x=5
To actually run something you will either need to define a main function that takes all the things you have defined and combines them in a meaningful way or append to the bottom of the code something similar to what you would write in the main function.

Categories