New to using functions in Python - python

I am trying to understand why newNameList is not defined:
ListofNames1 = ['Mark', 'Andrew']
ListofNames2 = ['Anjela', 'Lora']
names = ListofNames1
def greeting(names):
newNameList = []
for item in names:
newNameList.append(str(names))
return (names)
print(greeting(names))
def function2(newNameList):
for each in newNameList:
newNameList2.append(newNameList.upper())
return (newNameList2)
print(function2(newNameList))
The output
['Mark', 'Andrew']
...
NameError: name 'newNameList' is not defined.
The name error occurs on the last line in the code.

newNameList is only defined within the scope of function2. Since the print statement is not indented at the same level of function2 then newNameList is not visible to it. The three variables defined at a top-level scope are ListofNames1, ListofNames1, and names. These are the only three variables that can be passed to function2 in the print statement.

Yes, You can do it.
For example:
def use_greeting_function(name):
new_list_name = greeting(name)
Now new_list_name has the output of greeting function and you can use it in the function afterwards.

NameError: name 'newNameList' is not defined.
tells you what's wrong. You should have defined newNameList outside the greetings() function.
I have rewritten your code:
ListofNames1 = ['Mark', 'Andrew']
ListofNames2 = ['Anjela', 'Lora']
names = ListofNames1
newNameList = []
def greeting(names):
for item in names:
newNameList.append(names)
return names
print(greeting(names))
def function2(newNameList):
newNameList2 = []
for each in newNameList:
newNameList2.append(str(newNameList).upper())
return newNameList2
print(function2(newNameList))
And using the upper() method on a list doesn't work. Convert it to str first.

Related

Global variable not defined even though it appears in globals()

I wrote this code:
def openFile():
f = open("test.txt", "r")
mainInput = f.read()
global tupleMain
tupleMain = [tuple(mainInput.split(" ")) for mainInput in mainInput.strip(",").split("\n")]
As you can see, I have defined tupleMain as a global variable, but when I try to use it outside the function, I get:
NameError: name 'tupleMain' is not defined
If I run:
is_global = "tupleMain" in globals()
print(is_global)
The output is:
True
I just don't get why it says it's not defined if it's in globals() and have set it to global.
Thanks in advance
EDIT: I use the variable in the following function:
def tableFunction():
fname = [x[2] for x in tupleMain]
sname = [x[3] for x in tupleMain]
position = [x[1] for x in tupleMain]
salary = [x[4] for x in tupleMain]
team = [x[0] for x in tupleMain]
playerTable = PrettyTable()
playerTable.field_names= ["Surname", "First Name", "Salary", "Position", "Team"]
for x in tupleMain:
playerTable.add_row([x[3], x[2], x[4], x[1], x[0]])
print(playerTable)
You never called the function before using the global variable it declares in some other function, so the code inside the function which declares the variable as global never got executed. You need to at-least execute or call the function before referencing the global variable.
Either call the function before you use the global variable elsewhere or define the global variable at the module level inside your code.

Create a variable with the name of the contents of another variable, with the contents of the other variables contents

So i have code like this
varName = 'test'
varContents = 'something'
My question is:
How do i create a variable with the name of the contents of varName, having contents containing the contents of varContents?
Generally you'll want to avoid doing this - especially if you are dealing with user inputs, but you can use the exec() function. It runs a string passed into it as code, so you can do something like:
varName = 'test'
varContents = 'something'
exec(f"{varName} = '{varContents}'")
print(test)
A better way of storing data with a dynamic key is with a dict like this:
myDict = {}
varName = 'test'
varContents = 'something'
myDict[varName] = varContents
print(myDict[varName])
you can create variables like this :
locals()['newVar'] = "local variable"
print (newVar)
globals()['newGlobalVar'] = "global variable"
print (newGlobalVar)
so you could do this :
locals()[varName] = varContents
# Or
globals()[varName] = varContents

How to call functions and variables from a dictionary or a json file

I am trying to print a string, call functions and variables in a line.
such as [Hello! %(job), %(name)s, (function_name)]->[Hello! student, John, This is the function.]
json01.json
{
"test" : "Hello! %(job), %(name)s, (function_name)"
}
test01.py
import json
a = 'test'
name = 'John'
job = 'student'
def function_name(message):
print(message)
with open('json01.json') as json_file:
json_dict = json.load(json_file)
if a in json_dict:
print(json_dict[a] %locals())
#This works if there's only variables in the value
#but I don't know how to call functions when the value is not only function's name but also variables..
Is there any simple way to print whatever they are in the value?
or is there another way to do this work?
Sorry for the poor explanation and Thank you!
You can define your own function replacer using regular expressions. I defined an example syntax here as: Hello, !(function_name) where function_name is the name of the function that is called.
Using regular expressions we find all occurences of a function call and try to
evaluate them one by one. If successfull, we replace the function's name with the return value.
import re
def runfunctions(string):
# find all functions defined with our syntax
funcs = re.findall(r'!\((.*?)\)', string)
result = string
# iterate through found functions
for func in funcs:
try:
# try to evaluate with globals()[func]() and replace function call
# with return value
result = re.sub(r'!\(' + func + r'\)', globals()[func](), result)
except (KeyError, TypeError) as e:
# if func is not callable or does not exist catch error
print("Error while evaluating functions in string:", e)
# return final result
return result
Note: I used globals instead of locals as otherwise the function is not found.
You can use it like this:
if a in json_dict:
replaced_vars = json_dict[a] % locals()
replaced_funcs = runfunctions(replaced_vars)
print(replaced_funcs)

How do you initialize a global variable only when its not defined?

I have a global dictionary variable that will be used in a function that gets called multiple times. I don't have control of when the function is called, or a scope outside of the function I'm writing. I need to initialize the variable only if its not initialized. Once initialized, I will add values to it.
global dict
if dict is None:
dict = {}
dict[lldb.thread.GetThreadID()] = dict[lldb.thread.GetThreadID()] + 1
Unfortunately, I get
NameError: global name 'dict' is not defined
I understand that I should define the variable, but since this code is called multiple times, by just saying dict = {} I would be RE-defining the variable every time the code is called, unless I can somehow check if it's not defined, and only define it then.
Catching the error:
try:
_ = myDict
except NameError:
global myDict
myDict = {}
IMPORTANT NOTE:
Do NOT use dict or any other built-in type as a variable name.
A more idiomatic way to do this is to set the name ahead of time to a sentinel value and then check against that:
_my_dict = None
...
def increment_thing():
global _my_dict
if _my_dict is None:
_my_dict = {}
thread_id = lldb.thread.GetThreadID()
_my_dict[thread_id] = _my_dict.get(thread_id, 0) + 1
Note, I don't know anything about lldb -- but if it is using python threads, you might be better off using a threading.local:
import threading
# Thread local storage
_tls = threading.local()
def increment_thing():
counter = getattr(_tls, 'counter', 0)
_tls.counter = counter + 1

declaring a global dynamic variable in python

I'm a python/programming newbie and maybe my question has no sense at all.
My problem is that I can't get a variable to be global if it is dynamic, I mean I can do this:
def creatingShotInstance():
import movieClass
BrokenCristals = movieClass.shot()
global BrokenCristals #here I declare BrokenCristals like a global variable and it works, I have access to this variable (that is a shot class instance) from any part of my script.
BrokenCristals.set_name('BrokenCristals')
BrokenCristals.set_description('Both characters goes through a big glass\nand break it')
BrokenCristals.set_length(500)
Fight._shots.append(BrokenCristals)
def accesingShotInstance():
import movieClass
return BrokenCristals.get_name()#it returns me 'BrokenCristals'
but if instead of doing that I declare a string variable like this:
def creatingShotInstance():
import movieClass
a = 'BrokenCristals'
vars()[a] = movieClass.shot()
global a #this line is the only line that is not working now, I do not have acces to BrokenCristals class instance from other method, but I do have in the same method.
eval(a+".set_name('"+a+"')")
eval(a+".set_description('Both characters goes through a big glass\nand break it')")
eval(a+".set_length(500)")
Fight._shots.append(vars()[a])
def accesingShotInstance():
import movieClass
return BrokenCristals.get_name()#it returns me 'BrokenCristals is not defined'
I tried this :
global vars()[a]
and this:
global eval(a)
but It gives me an error. What should I do?
For completeness, here's the answer to your original question. But it's almost certainly not what you meant to do -- there are very few cases where modifying the scope's dict is the right thing to do.
globals()[a] = 'whatever'
Instead of a dynamic global variable, use a dict:
movies = {}
a = 'BrokenCristals'
movies[a] = movieClass.shot()
movies[a].set_name(a)
# etc
The global keyword specifies that a variable you're using in one scope actually belongs to the outer scope. Since you do not have nested scopes in your example, global doesn't know what you're trying to do. See Using global variables in a function other than the one that created them
Your code works fine!
It was just a spelling mistake and missing brackets!
First syntax error there are no square brackets:
File "main.py", line 6
global BrokenCristals
^
SyntaxError: name 'BrokenCristals' is assigned to before global declaration
Second syntax error there is no letter s on the end of global:
File "main.py", line 6
global [BrokenCristals]
^
SyntaxError: invalid syntax
Corrected syntax:
def creatingShotInstance():
import movieClass
BrokenCristals = movieClass.shot()
globals [BrokenCristals]
BrokenCristals.set_name('BrokenCristals')
BrokenCristals.set_description('Both characters goes through a big glass\nand break it')
BrokenCristals.set_length(500)
Fight._shots.append(BrokenCristals)
def accesingShotInstance():
import movieClass
return BrokenCristals.get_name()
Corrected syntax using declared string:
def creatingShotInstance():
import movieClass
a = 'BrokenCristals'
vars()[a] = movieClass.shot()
globals [a]
eval(a+".set_name('"+a+"')")
eval(a+".set_description('Both characters goes through a big glass\nand break it')")
eval(a+".set_length(500)")
Fight._shots.append(vars()[a])
def accesingShotInstance():
import movieClass
return BrokenCristals.get_name()

Categories