This question already has answers here:
Cannot change global variables in a function through an exec() statement?
(3 answers)
Closed 2 years ago.
I'm learning python and trying to use a function to choose and change a global variable.
I want to use the console to choose which variable to change and then choose the new value.
I'm using global inside the function to access the variables and I'm using exec() to proceed with the desired modification captured through input(). But something is not working.
Can someone please figure out what is wrong here?
name = "John"
age = 45
gender = "male"
def identify_yourself():
print("My name is " + name + ".")
print("I'm " + str(age) + " years old.")
print("I'm " + gender + ".")
def change_something():
global name, age, gender
something = input("Which variable do you want to change?\n> ")
# I then input "name"
new_value = input("Change to what?\n> ")
# I Then input "Paul"
exec(something + " = '" + new_value + "'")
identify_yourself()
identify_yourself()
# This first prints...
#
# My name is John.
# I'm 45 years old.
# I'm male.
change_something()
# On the second time this SHOULD print...
#
# My name is Paul.
# I'm 45 years old.
# I'm male.
#
# ... but it's not working.
# It keeps printing "My name is John" even after I run the change_something() function
The exec() uses globals() and locals() as defaults for their global and local variables. It defaults to changes in the locals(), not the globals. You therefore have to explicitly tell it to overwrite globals. You can do this the following way:
exec(something + " = '" + new_value + "'", globals())
Related
I have a global variable that needs to be altered by user input generated by a function.
I'm trying to make a Zork style text game and want the character name, input by the user during a character creation function, to alter a global variable.
I've been able to create a class to store character information and been able to display most of the information in the class on a mock command prompt I have appear when input options are available to the user.
I use a global variable to define the character's name until the character creation stage. I use the 'global' keyword in the creation() function to alter the 'name' variable with user input.
When the prompt is ready to be used it still only displays the name as 00 instead of the input generated during the creation() function
I am exceedingly novice. Any advice, tips or direction would be cherished.
import time
name = "00" ##this is what we want to change
##
def Intro():
print("\n\n\nWelcome to the game.")
time.sleep(1)
print("This is an attempt to make an interactive text based game.")
##
def Creation():
Character_name = input("\nWhat will your Character's name be: ")
time.sleep(1)
print("\nWelcome to the game " + Character_name + " \n" )
time.sleep(1.5)
Character_class = input("In one word, name " + Character_name + "'s profession: ")
t00n = Character_name + " the " + Character_class
global name ##here I am using the global keyword
name = t00n
time.sleep(1)
print("\n" + t00n + "\n")
time.sleep(2)
next_func = input("When ready type 'next' to begin.\n>>>:")
if next_func == "next":
segway()
else:
Jump()
##
def Jump():
Jump_Prompt = input("Just 'Jump' on in\n>>>: ")
if Jump_Prompt == "Jump":
segway1()
else:
Jump()
##
def segway():
print("A room with options to choose from")
prompt()
class Character:
def __init__(self, name, HP, full_HP, AtS, AR):
self.name = name ##should = t00n now?
self.hp = HP
self.full_HP = full_HP
self.AtS = AtS
self.AR = AR
def stat_bar(self):
return '{} {} {} {} {} {}'.format("[Name:]", self.name, "[HP:]", self.hp, "[Max HP:]", self.full_HP)
Player1 = Character(name, 100, 100, 1, 0)
##
def prompt():
_pr = input("<<< " + Character.stat_bar(Player1) + " >>> \n")
return _pr
#Begin
Intro()
Creation()
segway()
##The prompt() function still displays the name as 00 even tho the creation() function is using the 'global' keyword to change the 'name' variable to the user input.
You need to use the global keyword in your prompt, and update Player1.name with that global name
def prompt():
#Take name from global scope
global name
#Assign it to Player1 name
Player1.name = name
_pr = input("<<< " + Character.stat_bar(Player1) + " >>> \n")
return _pr
Then your prompt will work as intended, for example
Welcome to the game.
This is an attempt to make an interactive text based game.
What will your Character's name be: Joe
Welcome to the game Joe
In one word, name Joe's profession: Don
Joe the Don
When ready type 'next' to begin.
>>>:next
A room with options to choose from
<<< [Name:] Joe the Don [HP:] 100 [Max HP:] 100 >>>
Ahhh, took a little bit, but I think I found the problem.
You initialize Player 1 using the name variable before calling Creation(), where you change the global name variable, so Player1 is created with the original name “00.”
Move the line:
Player1 = Character(name, 100, 100, 1, 0)
Put it after Creation() at the bottom but before segway()
Python more or less executes any unindented code (code that isn’t in a function, class, etc.) from top to bottom.
So, moving from top to bottom in your program, it sets name to “00”, then creates Player1 with the original name, then calls Intro(), Creation() (which changes the name to t00n), and finally segway().
This question already has answers here:
input() error - NameError: name '...' is not defined
(15 answers)
Closed 4 years ago.
I was trying to get some input in python and I have no idea what is my problem
name = input("What's your name?")
age = int(input("How old are you?"))
year = str((100 - age) + 2018)
print("Hello "+ name + ",in " + year + "you'll be 100 y.o")
and when I use my name as input like "shayan", thats came out:
name = input("What's your name? ")
File "<string>", line 1, in <module>
NameError: name 'shayan' is not defined
I tri my code in "atom" , "sublime" , "visual studio code"
It's because you're on python 2, so input in python is basically eval(input(...)) in python 3, so it will take inputs as code, not strings, so gotta use raw_input in python 2:
name = raw_input("What's your name?")
age = input("How old are you?")
year = str((100 - age) + 2018)
print("Hello "+ name + ",in " + year + "you'll be 100 y.o")
This question already has answers here:
Returning a value from function?
(2 answers)
Closed 4 years ago.
im trying to make a simple text game for a school project and also make the code somewhat clean therefore I started using functions and classes.
The problem is im stuck on trying to access a variable from a function that asks the user for their username.
Here is my code
def playername():
print("What is your name?")
playername = input()
how can I access the playername variable without running the whole function again so once I run it at the start and get the username I can use that same input username later on in the code?
You can define your function like this:
def get_playername():
playername = input('Whats is your name? ')
return playername
Then,use it:
name = get_playername()
store it as a variable outside of function. for example string playerName = playername() and add return playername to the end of the function "playername"
def playername():
print("What is your name?")
playername = input()
return playername
def main():
playerName = playername()
print(playerName)
main()
Firstly, it's a good idea to name your function and variables differently. So, I'd use something like "name" to store the name of the player.
You can print the question and store the value at the same step with the input() function
def playername():
name = input("Enter you name: ")
print("Hello {}".format(name))
return name
name = playername()
playername variable is limited (scoped) to playername function, it cannot be accessed from outside the function
You should return the playername value, so that the function caller can store and use this value
def playername():
print("What is your name?")
playername = input()
return playername
def main():
my_playername = playername()
# use my_playername as much as you like
...
main()
Returning values from a function is a basic programming skill. I strongly recommend that you work through class materials or a tutorial on the topic.
def get_player_name():
print("What is your name?")
name = input() # Do NOT give two program objects the same name.
return name
# Main Program
victim_name = get_player_name()
I initate a variable globally then when I go to change the variable it's type goes from dictionary (good) to string ( bad) and I am kinda sure why but not really. I am not 100% on python scoping.
The code in full is below please notice I have alot of print statements which I was using as testing. I am including all the code to the point of the issue to give you all a full grasp of what I am trying to do.
totalEntries = 0
print 'this is first ' + str((type(totalEntries))) #prints type int (good)
perPage = 0
currentPage = 1
Pcity = ''
api_data = ''
is_last_page = False
apiCallNum = 1
tableDefined = False
def getApiData(city):
global Pcity
global apiCallNum
global apiEndpoint
Pcity = city
apiEndpoint = #just a link ignore this
api_data = requests.get(apiEndpoint).json()
print(api_data)
print('your testing this' + str(type(api_data))) #prints dict (good)
print ("Current API Call " + str(apiCallNum))
apiCallNum += 1
print('your testing this' + str(type(api_data))) #prints dict (good)
def populateVars():
global totalEntries
print "this is second " + str(type(totalEntries)) #prints int (good)
print('your testing this' + str(type(api_data))) #prints string (bad)
totalEntries = api_data['total_entries']
thank you all
Assignments made to api_data inside getApiData won't be visible anywhere else because you didn't mark it as global.
Add global api_data to the beginning of getApiData.
Incidentally, you only need the global statement if you want to assign to a global variable - you can access their values just fine without the statement. So strictly speaking you don't need global apiEndpoint.
This question already has answers here:
Using global variables in a function
(25 answers)
Closed 7 years ago.
I get a Local variable 'first' referenced before assignment error when I run my code.
def start():
global a
a = [" "," "," "," "," "," "," "," "," "]
global first
first = randrange(2)
def reverse():
if first == 1:
first = 0
else:
first = 1
if first == 1:
turn = "X"
else:
turn = "O"
That is just a part of my code where the error occurs. However when I paste the code into IDLE it works no problem so I don't know why this is happening.
Anyways, my full code (unfinished Tic Tac Toe):
from os import name
from os import system
from random import randrange
from time import sleep
def cls():
system(['clear','cls'][name == 'nt'])
def start():
global a
a = [" "," "," "," "," "," "," "," "," "]
global first
first = randrange(2)
def reverse():
if first == 1:
first = 0
else:
first = 1
if first == 1:
turn = "X"
else:
turn = "O"
while True:
reverse()
cls()
printBoard()
print ""
print "Its %s's turn." % (turn)
print ""
move = raw_input("Enter your move (1-9): ")
if move.isdigit() == True:
move = int(move)
if move in range(9):
move = move - 1
if a[move] == " ":
a[move] = turn
else:
print "Incorrect move: Place taken"
reverse()
sleep(2)
else:
print "Incorrect move: Number out of range"
sleep(2)
else:
print "Incorrect move: Move not a number"
sleep(2)
def printBoard():
cls()
print a[0],"|",a[1],"|",a[2]
print "---------"
print a[3],"|",a[4],"|",a[5]
print "---------"
print a[6],"|",a[7],"|",a[8]
start()
Python scans a function body for any assignments, and if they aren't explicitly declared global, then it creates a local scope variable for that name. Because you assign to first in your reverse() function, and you haven't explicitly declared first to be global within that function's scope, python creates a local variable named first that hides the global one.
It doesn't matter that the assignment comes after the comparison; python implicitly declares all local variables at the beginning of the function.
To fix this you can declare first to be global within the reverse() function, but as others have said, globals should be avoided when possible.