This question already has answers here:
Short description of the scoping rules?
(9 answers)
Closed 4 years ago.
Mac OS 10.13.16
Python 3.7
PyCharm
I was going through a tutorial for this guessing game and I came across something I thought was weird. On line 18 I call on the guess variable, which I though was a Local Variable under the for loop created above it, let's me call on it as if it were a Global. I though if a var is declared within a function or loop it makes it a local. Can someone help explain this to me.
import random
print("Hello what is your name?")
name = input()
print("Well " + name + " I am thinking of a number between 1 and 20")
secretNumber = random.randint(1,20)
for guessesTaken in range(1, 7):
print("Take a guess.")
guess = int(input())
if guess < secretNumber:
print("Sorry to low")
elif guess > secretNumber:
print("Sorry to high")
else:
break
if guess == secretNumber:
print("Great job " + name + ". You guessed my number in " + str(guessesTaken) + " moves.")
else:
print("Sorry the number I was thinking of is " + str(secretNumber))
Taken from another answer: It appears to be a design decision in the python language. Functions still have local variables, but for loops don't create local variables.
Previous proposals to make for-loop variables local to the loop have stumbled on the problem of existing code that relies on the loop variable keeping its value after exiting the loop, and it seems that this is regarded as a desirable feature.
http://mail.python.org/pipermail/python-ideas/2008-October/002109.html
Excerpt from Python's documentation:
A block is a piece of Python program text that is executed as a unit.
The following are blocks: a module, a function body, and a class
definition. Each command typed interactively is a block. A script file
(a file given as standard input to the interpreter or specified as a
command line argument to the interpreter) is a code block. A script
command (a command specified on the interpreter command line with the
‘-c’ option) is a code block. The string argument passed to the
built-in functions eval() and exec() is a code block.
And:
A scope defines the visibility of a name within a block. If a local
variable is defined in a block, its scope includes that block. If the
definition occurs in a function block, the scope extends to any blocks
contained within the defining one, unless a contained block introduces
a different binding for the name.
When a name is used in a code block, it is resolved using the nearest
enclosing scope. The set of all such scopes visible to a code block is
called the block’s environment.
Local variables are visible anywhere in the same code block. A for loop is not a code block by definition, however, and therefore the local variable defined in your for loop is still visible after the loop, within the same module.
Related
This question already has answers here:
Cannot call a variable from another function
(4 answers)
Closed 2 years ago.
I have got a database program to keep data in, and I can't solve this problem:
I have got two functions. When you input A into the program
the function called addy() starts
and ask for more input into a variable
then it returns to the main screen,
then the user can Input S
which starts Show()
and then it's supposed to show what you have added into the variable
PROBLEM:
It's not getting the value from the previous definition.
CODE:
def addy():
os.system('cls')
addel = input('what is the name of the operating system?: \n')
os.system('cls')
time.sleep(1)
print(addel + ' Has been added to the database!')
time.sleep(2)
program()
def show():
print('Heres a list of the operating systems you have added:')
time.sleep(5)
program()
addel = addy()
print(addel) # this should print the value from the previous function
The are 2 reasons why
Addel is a local variable not a global one. Therefore, you can only use it in your addy function.
Say your intent was not to use it which is what it seems, you wrote
addel = addy()
the function addy has no return value so your code wont work.
to fix this write
return addel
as the last line in your addy function then it will work because now the function has a return value.
choice="y"
again="y"
coin=0
credit=0
allowed=[0,10,20,50,100,200]
def money_insert():
global again
global coin
global credit
global allowed
while again=="y":
try:
coin=int(input("insert coin"))
except:
print("thats not a coin")
while coin not in allowed:
print("invalid coin")
coin = 0
credit+=coin
again=input("another coin y/n?")
money_insert()
print("you have",credit,"p")
print("")
print("**********")
print("**1 coke 100p**")
print("*2 haribo 100p*")
print("*3 galaxy 100p*")
print("**4 mars 100p**")
print("*5 crisps 50p*")
selection=int(input("what would you like? 1-5"))
while choice=="y":
if selection==1:
if credit>99:
print("Here's your coke")
credit-=100
else:
print("not enough credit")
money_insert()
The last bit keeps displaying not enough credit continuously and I don’t know what to do
Sorry if this is a really dumb question I’m really new to python
choice is never altered, so you can never escape the while choice='y': loop. Then assuming the selection chosen was 1 you continue on to buying your coke. If you have previously entered coins via the money_insert function, presumably you would have at some point answered no to the question "another coin y/n?". You never reset the again variable, so subsequent calls to money_insert will just skip your for loop and not let you enter more money. You then basically follow the same path over and over again: while choice='y': → if selection==1: → if credit>99: ... else: → print("not enough credit")
I should also like to point out the issue with your money_insert function is a direct result of using a global variable where you don't need to. Global variables can be useful in certain instances, but they are generally frowned upon for cases such as this where you generally assume running a function with the same inputs will give the same result, but since the global variable has changed, the function now behaves differently. In this instance you don't need again to be global because it isn't used anywhere else, so you can move again='y' inside the function definition and remove the line global again to solve that particular issue. The same applies to coin and allowed as they aren't used anywhere but inside the function, and although they aren't causing a problem at the moment, leaving them available outside the function to be changed could cause a problem if you try to name something else by the same name somewhere else.
I thoroughly searched for an answer to my question but couldn't find anything that would explain my results. I truly hope that anyone of you can point me in the right direction.
At the moment I am trying to program a text-based adventure game using Python 3 in order to better understand the language.
While doing so I created a function that should ask the user for input and print a specific statement depending on the users input. In case the users input is invalid the function should then keep asking for input until it is valid.
Unfortunately the function only seems to keep asking for input, without ever executing the if/elif statements within the function. Due to no errors being shown I am currently at a loss as to why this is the case...
print("If You want to start the game, please enter 'start'." + "\n" +
"Otherwise please enter 'quit' in order to quit the game.")
startGame = True
def StartGame_int(answer):
if answer.lower() == "start":
startGame = False
return "Welcome to Vahlderia!"
elif answer.lower() == "quit":
startGame = False
return "Thank You for playing Vahlderia!" + "\n" + "You can now close
the window."
else:
return "Please enter either 'r' to start or 'q' to quit the game."
def StartGame():
answ = input("- ")
StartGame_int(answ)
while startGame == True:
StartGame()
You fell into the scoping trap: you are creating a new variable startGame inside the function that is discarded after you leave it. You would instead need to modify the global one:
def StartGame_int(answer):
global startGame # you need to specify that you want to modify the global var
# not create a same-named var in this scope
# rest of your code
This other SO questions might be of interest:
Python scoping rules
Asking the user for input until they give a valid response
Use of global keyword
and my all time favorite:
How to debug small programs (#1) so you enable yourself to debug your own code.
The last one will help you figure out why your texts that you return are not printed and why the if does not work on 'r' or 'q' and whatever other problems you stumble into. It will also show you that your if are indeed executed ;o)
Other great things to read for your text adventure to avoid other beginner traps:
How to copy or clone a list
How to parse a string to float or int
How to randomly select an item from a list
Okay so ill apologize in advance if this question has previously been answered but I've looked thoroughly and cant seem to find anything that works. Im making a very simple game where you pretty much just have to guess a number between 1 and 1000 and if its incorrect the computer guesses a number either 1 above or below your guess. here is a function I've made to determine if the guess was too low
def numLow(userInput, low, high):
while userInput < num:
print ("The guess of {0} is low".format(userInput))
compGuess = (userInput + 1)
print ("My guess is {0}".format(compGuess))
low = (userInput + 1)
if compGuess < num:
print("The guess of {0} is low".format(compGuess))
userInput = int(input("Enter a value between {0} and
{1}:".format(low, high)))
else:
print("The guess of {0} is correct!".format(compGuess))
print("I WON!!!")
showTermination()
return (userInput, low)
now my issue is that i want to change the global variables userInput, low and high in the function. ive tried inserting
global userInput
global high
global low
before the function but it doesnt seem to work and if i put the globals inside the function i get "name 'userInput' is parameter and global". now im guessing the while loop is causing the problem but i cant seem to troubleshoot it. Im totally new to coding so i apologize if im breaking any coding rules or anything. Thanks for the help.
userInput for example is an input parameter to your function. The error message says exactly what the problem is here. You wanna use a global variable called userInput and you have an input parameter called userInput which are two different things for python. When userInput should be global then just define it somewhere globally like userInput = None and then instead of reaching it into the function as parameter just write in the function global userInput and python will know you are referencing to the globally instantiated variable. Both at the same time does not work.
Use globals() like this:
globals()['userInput'] = ...
I am very very new to Python and before this I only used extremely simple "programming" languages with labels and gotos. I am trying to make this code work in Sikuli:
http://i.imgur.com/gbtdMZF.png
Basically I want it to loop the if statement until any of the images is found, and if one of them is found, it executes the right function and starts looping again until it detects a new command.
I have been looking for tutorials and documentation, but I'm really lost. I think my mind is too busy trying to go from a goto/label to an organized programming language.
If someone could give me an example, I would appreciate it a lot!
In Python indentation matters, your code should look like this:
def function():
if condition1:
reaction1()
elif condition2:
reaction2()
else:
deafult_reaction()
I recommend reading the chapter about indentation in Dive Into Python as well as PEP 0008.
x = input( "please enter the variable")
print(" the Variable entered is " + x)
myfloat = int(x)
def compare (num):
if num%2 == 0:
print(" entered variable is even")
else:
print("entered variable is odd")
compare(myfloat)