I am trying to set a new variable to reference a variable inside a function. My pseudo code goes like this:
def myfunction():
a bunch of stuff that results in
myvariable = "Some Text"
Further down the code I have this:
for something in somethinglist:
if something == iteminsomethinglist:
myfunction()
mynewvariable1 = myvariable
elif something == iteminsomethinglist:
myfunction()
mynewvariable2 = myvariable
else:
mynewvariable3 = myvariable
I keep getting an error message that says something like: name 'myvariable' is not defined
I guess I thought that if I called the function, it processes some stuff, I pass result into a variable and then reference that variable to a more unique variable, it would store it....but it's not.
Edit: I am attaching my code because it I wasn't clear enough in my first post. There is a variable within my function I wanted to reference outside of it (actually there are 2) I apologize for not making it clear enough. I though my original psuedo code proposed the question well enough. I also have a feeling that this might not be the best approach. Possible calling 2 functions would be more appropriate? My code is below:
def datetypedetector():
rows = arcpy.SearchCursor(fc)
dateList = []
for row in rows:
dateList.append(row.getValue("DATE_OBSERVATION").strftime('%m-%d-%Y'))
del row, rows
newList = sorted(list(set(dateList)))
dates = [datetime.strptime(d, "%m-%d-%Y") for d in newList]
date_ints = set([d.toordinal() for d in dates])
if len(date_ints) == 1:
DTYPE = "Single Date"
#print "Single Date"
elif max(date_ints) - min(date_ints) == len(date_ints) - 1:
DTYPE = "Range of Dates"
#print "Range of Dates"
else:
DTYPE = "Multiple Dates"
#print "Multiple Dates"
fcList = arcpy.ListFeatureClasses()
for fc in fcList:
if fc == "SO_SOIL_P" or fc == "AS_ECOSITE_P":
datetypedetector()
ssDate = newList
print fc + " = " + str(ssDate)
ssDatetype = DTYPE
print ssDatetype
elif fc == "VE_WEED_P":
datetypedetector()
vwDate = newList
print fc + " = " + str(vwDate)
vwDatetype = DTYPE
print vwDatetype
else:
datetypedetector()
vrDate = newList
print fc + " = " + str(vrDate)
vrDatetype = DTYPE
print vrDatetype
As written, myvariable is only defined within the scope of myfunction.
To make the value in that variable available outside of the function you can return it from the function:
def myfunction():
myvariable = "Some Text"
return myvariable
And then use it later like this:
for something in somethinglist:
if something == iteminsomethinglist:
mynewvariable1 = myfunction()
Edit: new information added to question.
Your indentation seems slightly off, but that may just be copy-paste trouble.
I think what you want to do is something like this:
Call the datetypedetector function taking fc as an argument.
Return DTYPE from that function for later use.
So first change the function signature to:
def datetypedetector(fc):
^^
And the final statement in datetypedetector to:
return DTYPE
And then pass fc as an argument when you call it, and the final step is to get the DTYPE back from the function by assigning to it datetypedetector's return value.
for fc in fcList:
if fc == "SO_SOIL_P" or fc == "AS_ECOSITE_P":
DTYPE = datetypedetector(fc)
...
A much better way to organize the code would be to do something like this:
def myfunction():
return "Some Text"
for something in somethinglist:
if something == iteminsomethinglist:
mynewvariable1 = myfunction()
elif something == iteminsomethinglist:
mynewvariable2 = myfunction()
else:
mynewvariable3 = myfunction()
Related
This question already has answers here:
Getting the name of a variable as a string
(32 answers)
Closed 4 months ago.
Is it possible to get the original variable name of a variable passed to a function? E.g.
foobar = "foo"
def func(var):
print var.origname
So that:
func(foobar)
Returns:
>>foobar
EDIT:
All I was trying to do was make a function like:
def log(soup):
f = open(varname+'.html', 'w')
print >>f, soup.prettify()
f.close()
.. and have the function generate the filename from the name of the variable passed to it.
I suppose if it's not possible I'll just have to pass the variable and the variable's name as a string each time.
EDIT: To make it clear, I don't recommend using this AT ALL, it will break, it's a mess, it won't help you in any way, but it's doable for entertainment/education purposes.
You can hack around with the inspect module, I don't recommend that, but you can do it...
import inspect
def foo(a, f, b):
frame = inspect.currentframe()
frame = inspect.getouterframes(frame)[1]
string = inspect.getframeinfo(frame[0]).code_context[0].strip()
args = string[string.find('(') + 1:-1].split(',')
names = []
for i in args:
if i.find('=') != -1:
names.append(i.split('=')[1].strip())
else:
names.append(i)
print names
def main():
e = 1
c = 2
foo(e, 1000, b = c)
main()
Output:
['e', '1000', 'c']
To add to Michael Mrozek's answer, you can extract the exact parameters versus the full code by:
import re
import traceback
def func(var):
stack = traceback.extract_stack()
filename, lineno, function_name, code = stack[-2]
vars_name = re.compile(r'\((.*?)\).*$').search(code).groups()[0]
print vars_name
return
foobar = "foo"
func(foobar)
# PRINTS: foobar
Looks like Ivo beat me to inspect, but here's another implementation:
import inspect
def varName(var):
lcls = inspect.stack()[2][0].f_locals
for name in lcls:
if id(var) == id(lcls[name]):
return name
return None
def foo(x=None):
lcl='not me'
return varName(x)
def bar():
lcl = 'hi'
return foo(lcl)
bar()
# 'lcl'
Of course, it can be fooled:
def baz():
lcl = 'hi'
x='hi'
return foo(lcl)
baz()
# 'x'
Moral: don't do it.
Another way you can try if you know what the calling code will look like is to use traceback:
def func(var):
stack = traceback.extract_stack()
filename, lineno, function_name, code = stack[-2]
code will contain the line of code that was used to call func (in your example, it would be the string func(foobar)). You can parse that to pull out the argument
You can't. It's evaluated before being passed to the function. All you can do is pass it as a string.
#Ivo Wetzel's answer works in the case of function call are made in one line, like
e = 1 + 7
c = 3
foo(e, 100, b=c)
In case that function call is not in one line, like:
e = 1 + 7
c = 3
foo(e,
1000,
b = c)
below code works:
import inspect, ast
def foo(a, f, b):
frame = inspect.currentframe()
frame = inspect.getouterframes(frame)[1]
string = inspect.findsource(frame[0])[0]
nodes = ast.parse(''.join(string))
i_expr = -1
for (i, node) in enumerate(nodes.body):
if hasattr(node, 'value') and isinstance(node.value, ast.Call)
and hasattr(node.value.func, 'id') and node.value.func.id == 'foo' # Here goes name of the function:
i_expr = i
break
i_expr_next = min(i_expr + 1, len(nodes.body)-1)
lineno_start = nodes.body[i_expr].lineno
lineno_end = nodes.body[i_expr_next].lineno if i_expr_next != i_expr else len(string)
str_func_call = ''.join([i.strip() for i in string[lineno_start - 1: lineno_end]])
params = str_func_call[str_func_call.find('(') + 1:-1].split(',')
print(params)
You will get:
[u'e', u'1000', u'b = c']
But still, this might break.
You can use python-varname package
from varname import nameof
s = 'Hey!'
print (nameof(s))
Output:
s
Package below:
https://github.com/pwwang/python-varname
For posterity, here's some code I wrote for this task, in general I think there is a missing module in Python to give everyone nice and robust inspection of the caller environment. Similar to what rlang eval framework provides for R.
import re, inspect, ast
#Convoluted frame stack walk and source scrape to get what the calling statement to a function looked like.
#Specifically return the name of the variable passed as parameter found at position pos in the parameter list.
def _caller_param_name(pos):
#The parameter name to return
param = None
#Get the frame object for this function call
thisframe = inspect.currentframe()
try:
#Get the parent calling frames details
frames = inspect.getouterframes(thisframe)
#Function this function was just called from that we wish to find the calling parameter name for
function = frames[1][3]
#Get all the details of where the calling statement was
frame,filename,line_number,function_name,source,source_index = frames[2]
#Read in the source file in the parent calling frame upto where the call was made
with open(filename) as source_file:
head=[source_file.next() for x in xrange(line_number)]
source_file.close()
#Build all lines of the calling statement, this deals with when a function is called with parameters listed on each line
lines = []
#Compile a regex for matching the start of the function being called
regex = re.compile(r'\.?\s*%s\s*\(' % (function))
#Work backwards from the parent calling frame line number until we see the start of the calling statement (usually the same line!!!)
for line in reversed(head):
lines.append(line.strip())
if re.search(regex, line):
break
#Put the lines we have groked back into sourcefile order rather than reverse order
lines.reverse()
#Join all the lines that were part of the calling statement
call = "".join(lines)
#Grab the parameter list from the calling statement for the function we were called from
match = re.search('\.?\s*%s\s*\((.*)\)' % (function), call)
paramlist = match.group(1)
#If the function was called with no parameters raise an exception
if paramlist == "":
raise LookupError("Function called with no parameters.")
#Use the Python abstract syntax tree parser to create a parsed form of the function parameter list 'Name' nodes are variable names
parameter = ast.parse(paramlist).body[0].value
#If there were multiple parameters get the positional requested
if type(parameter).__name__ == 'Tuple':
#If we asked for a parameter outside of what was passed complain
if pos >= len(parameter.elts):
raise LookupError("The function call did not have a parameter at postion %s" % pos)
parameter = parameter.elts[pos]
#If there was only a single parameter and another was requested raise an exception
elif pos != 0:
raise LookupError("There was only a single calling parameter found. Parameter indices start at 0.")
#If the parameter was the name of a variable we can use it otherwise pass back None
if type(parameter).__name__ == 'Name':
param = parameter.id
finally:
#Remove the frame reference to prevent cyclic references screwing the garbage collector
del thisframe
#Return the parameter name we found
return param
If you want a Key Value Pair relationship, maybe using a Dictionary would be better?
...or if you're trying to create some auto-documentation from your code, perhaps something like Doxygen (http://www.doxygen.nl/) could do the job for you?
I wondered how IceCream solves this problem. So I looked into the source code and came up with the following (slightly simplified) solution. It might not be 100% bullet-proof (e.g. I dropped get_text_with_indentation and I assume exactly one function argument), but it works well for different test cases. It does not need to parse source code itself, so it should be more robust and simpler than previous solutions.
#!/usr/bin/env python3
import inspect
from executing import Source
def func(var):
callFrame = inspect.currentframe().f_back
callNode = Source.executing(callFrame).node
source = Source.for_frame(callFrame)
expression = source.asttokens().get_text(callNode.args[0])
print(expression, '=', var)
i = 1
f = 2.0
dct = {'key': 'value'}
obj = type('', (), {'value': 42})
func(i)
func(f)
func(s)
func(dct['key'])
func(obj.value)
Output:
i = 1
f = 2.0
s = string
dct['key'] = value
obj.value = 42
Update: If you want to move the "magic" into a separate function, you simply have to go one frame further back with an additional f_back.
def get_name_of_argument():
callFrame = inspect.currentframe().f_back.f_back
callNode = Source.executing(callFrame).node
source = Source.for_frame(callFrame)
return source.asttokens().get_text(callNode.args[0])
def func(var):
print(get_name_of_argument(), '=', var)
If you want to get the caller params as in #Matt Oates answer answer without using the source file (ie from Jupyter Notebook), this code (combined from #Aeon answer) will do the trick (at least in some simple cases):
def get_caller_params():
# get the frame object for this function call
thisframe = inspect.currentframe()
# get the parent calling frames details
frames = inspect.getouterframes(thisframe)
# frame 0 is the frame of this function
# frame 1 is the frame of the caller function (the one we want to inspect)
# frame 2 is the frame of the code that calls the caller
caller_function_name = frames[1][3]
code_that_calls_caller = inspect.findsource(frames[2][0])[0]
# parse code to get nodes of abstract syntact tree of the call
nodes = ast.parse(''.join(code_that_calls_caller))
# find the node that calls the function
i_expr = -1
for (i, node) in enumerate(nodes.body):
if _node_is_our_function_call(node, caller_function_name):
i_expr = i
break
# line with the call start
idx_start = nodes.body[i_expr].lineno - 1
# line with the end of the call
if i_expr < len(nodes.body) - 1:
# next expression marks the end of the call
idx_end = nodes.body[i_expr + 1].lineno - 1
else:
# end of the source marks the end of the call
idx_end = len(code_that_calls_caller)
call_lines = code_that_calls_caller[idx_start:idx_end]
str_func_call = ''.join([line.strip() for line in call_lines])
str_call_params = str_func_call[str_func_call.find('(') + 1:-1]
params = [p.strip() for p in str_call_params.split(',')]
return params
def _node_is_our_function_call(node, our_function_name):
node_is_call = hasattr(node, 'value') and isinstance(node.value, ast.Call)
if not node_is_call:
return False
function_name_correct = hasattr(node.value.func, 'id') and node.value.func.id == our_function_name
return function_name_correct
You can then run it as this:
def test(*par_values):
par_names = get_caller_params()
for name, val in zip(par_names, par_values):
print(name, val)
a = 1
b = 2
string = 'text'
test(a, b,
string
)
to get the desired output:
a 1
b 2
string text
Since you can have multiple variables with the same content, instead of passing the variable (content), it might be safer (and will be simpler) to pass it's name in a string and get the variable content from the locals dictionary in the callers stack frame. :
def displayvar(name):
import sys
return name+" = "+repr(sys._getframe(1).f_locals[name])
If it just so happens that the variable is a callable (function), it will have a __name__ property.
E.g. a wrapper to log the execution time of a function:
def time_it(func, *args, **kwargs):
start = perf_counter()
result = func(*args, **kwargs)
duration = perf_counter() - start
print(f'{func.__name__} ran in {duration * 1000}ms')
return result
I have a program that I want to be able to print all of the instances of each variable using my method that I created. Problem is I can't figure out a way to print them since each are listed under a different variable that aren't configured from hardcoding them in and I need a way to automatically recall them in my code.
class fit:
def __init__(self,day,did,workout='Not Recorded',time='An unknown amount of',calories='An unknown amount of'):
self.day = day
self.did = did
if did.lower()=='no':
self.workout = 'Not Recorded'
self.time = "An unknown amount of Minutes"
self.calories = "An unknown amount of Calories"
else:
self.workout = workout
self.time = "{} Minutes".format(time)
self.calories = "{} Calories".format(calories)
def formate(self):
self.formate = "{}:\n\nDid you work out: {}\nWorkout focus: {}\nYou worked out for: {}\nYou burned: {}\n\n----------------------------------------------------------".format(self.day,self.did,self.workout,self.time,self.calories)
return self.formate
def reader(day,index):
file = open('readme.txt')
file = file.read()
stripped = file.rsplit("\n")
for i in range(len(stripped)):
stripped[i] = stripped[i].rsplit(" ")
del stripped[-1]
if int(index) >= len(stripped[day-1]):
return "none"
else:
return stripped[day-1][index]
x = 0
def create_new_instance(class_name,instance_name):
globals()[instance_name] = class_name(reader(x,0),reader(x,1),reader(x,2),reader(x,3),reader(x,4))
print('Class instance {} created'.format(instance_name))
while True:
try:
x+=1
ins = 'day_' + str(x)
create_new_instance(fit,ins)
except:
break
break
def printer(instance):
print(.formate())
while True:
x+=1
inst = 'day_' + str(x)
printer(inst)
An example of this might be that I have 8 lines of data from a text document and I have a system that creates instances of day_1, day_2, day_3 ect until day_8 and then I want to print each of those instances out, but again I don't have those instances directly hardcoded into my code so I don't know how I'd do it. I've tried looking into maybe a while loop and increasing a variable by 1 and concatenating it with day and trying to make a variable out of that but the my limited experience with python isn't helping.
A very unpythonic and ugly way would be to use exec, for example:
day_3=5
x = 'day_'+'3'
exec("print("+x+")")
I would recommend another way to store your variables though.
I'm working on a school project. I made a test version of my program, because I'm new to Python and I only have experience with C#, so I'm still learning te basics. My problem is the following:
Before the function "Fill_Array()" I declared a variable (" max_element_var") that is supposed to store the max number of elements that can be stored in the array ("content_array"). Later in the function I change it's value to the input of the console, which happens, and the function runs as it should, the only problem being is that outside the function the value of " max_element_var" stays "None". What should I do in order to fix this?
#__Test__#
def Test():
class Que:
def __init__(self, content, max_element ,actual_elements):
self.content = content
self.max_element = max_element
self.actual_elements = actual_elements
max_element_var = None
content_array = []
def Fill_array():
print("What should be the max number of elements that can be stored in the array? (Type in an integer!)")
max_element_var = int(input())
if(max_element_var>0):
import random
random_var = random.randrange(0,max_element_var)
for x in range(max_element_var-random_var):
content_array.append(x)
else:
print("It has to be more than 0!")
Fill_array()
Fill_array()
actual_elements_var = len(content_array)
que = Que (content_array, max_element_var, actual_elements_var)
print("Content: ", que.content)
print("Max number of elements: ", que.max_element)
print("Actual number of elements: ", que.actual_elements)
#__Test__#
#__Full__#
def Full():
pass
#__Full__#
#__Version_selector__#
def Version_selector():
print("Which version should be used? (Type in the number!)")
print("1 - Test")
print("2 - Full")
answer = int(input())
if(answer == 1):
Test()
Version_selector()
elif(answer == 2):
Full()
Version_selector()
#__Version_selector__#
Version_selector()
In python variables are automatically created as local, in the scope of the function which used them alone.
To solve your problem you may either
(1) return the variable, passing it from one function the other explicitly.
(2) declare it as global so all functions have access to it.
More about scopes here and here.
Consider the following code. In the code below you persumably change the value of x but in fact there is a big difference between the x inside the function and outside. The x inside the function is a local variable and will "disappear" once the function ends. If you want to save the value of x you must use return x and save the outcome to a variable. For example, See the function a_saving_example(x)
you may also use a global variable though some say it is bad practice and it is better to use return in your function.
def times_two(x):
x = x * 2
x = 5
print(x)
times_two(x)
print(x)
output:
5
5
saving example:
def a_saving_example(x):
x = x * 2
return x
x = 5
print(x)
x = a_saving_example(x)
print(x)
output:
5
10
Modified code to correct some issues.
Import normally done at top of module (not within functions)
Remove nested class definition inside function (obfuscates things in simple code)
Changed recursive calls to a while loop (a better way to repeat execution of a function from beginning in Python since no tail recursion).
Code Refactoring
import random
class Que:
def __init__(self, content, max_element ,actual_elements):
self.content = content
self.max_element = max_element
self.actual_elements = actual_elements
def Fill_array():
" Returns requested size and array "
while True:
prompt = """"What should be the max number of elements that can be stored in the array? Type in an integer!: """
max_element_var = int(input(prompt))
if max_element_var > 0:
random_var = random.randrange(0,max_element_var)
return max_element_var, [x for x in range(max_element_var-random_var)]
else:
print("It has to be more than 0!")
def Test():
max_element_var, content_array = Fill_array()
actual_elements_var = len(content_array)
que = Que (content_array, max_element_var, actual_elements_var)
print("Content: ", que.content)
print("Max number of elements: ", que.max_element)
print("Actual number of elements: ", que.actual_elements)
#__Test__#
#__Full__#
def Full():
pass
#__Full__#
#__Version_selector__#
def Version_selector():
while True:
prompt = """Which version should be used? (Type in the number!)
1 - Test
2 - Full
3 - Quit\n\t"""
answer = int(input(prompt))
if answer == 1:
Test()
elif answer == 2:
Full()
else:
break
#__Version_selector__#
Version_selector()
Hi I'm a beginner programmer. I don't know how can I call a variable from function.
I have two def calcular() and guardar(). I get some variables from calcular() that I will call later, but when I call variables in guardar(), it tells me that variable is not defined. I tried making global var, but it doesn't work. Hope you can help me
This is a little of my code...
def calcular():
if nClient == "":
texto = ("Inserta Numero de cliente")
ventanaMensaje(texto)
else:
if cl1=="":
texto = ("Inserta Clave")
ventanaMensaje(texto)
else:
if aB1 == "":
texto = ("Inserta Cantidad")
ventanaMensaje(texto)
else:
try:
clt = open("preciosEsp.txt","r+")
lClt = clt.readlines()
rClt = lClt[0]
sClt = rClt.split("'")
nRClt = sClt[0]
if nClient == nRClt:
cReg=sClt[1]
if cl1== cReg:
prc=sClt[2]
else:
k=1
while cl1 != cReg:
cReg=sClt[k]
k=k+2
if cl1== cReg:
ñ=k-1
prc=sClt[ñ]
else:
x = 0
while nClient != nRClt:
rClt = lClt[x]
sClt = rClt.split("'")
nRClt = sClt[0]
x=x+1
if nClient == nRClt:
cReg=sClt[1]
if cl1==cReg:
prc=sClt[2]
else:
k=1
while cl1 != cReg:
cReg=sClt[k]
k=k+2
if cl1== cReg:
ñ=k-1
prc=sClt[ñ]
indice=int(prc)+3
pdcts = open("productos.txt","r+")
lPdcts = pdcts.readlines()
rPdcts = lPdcts[0]
sPdcts= rPdcts.split("'")
nPdcts = sPdcts[0]
t = 0
if cl1 == nPdcts:
precio1=sPdcts[indice]
global txtD1################## MAKE A GLOBAL VAR
txtD1=sPdcts[1] #### THIS IS THE VARIABLE ########
def guardar():
guardarDatos = (n+txtD1) ################# I CALL HERE, BUT TELL ME THAT VARIABLE IS NOT DEFINED
If you really want a global variable, you'd define it outside of any function
txtD1 = None
def calcular():
...
it will then exist at module level. However, globals are rarely (read: never) the solution you should be using, instead you should be returning information from functions rather than modifying global state. You'd then pass that information into another function to use.
The global keyword in python says that you are referencing a global variable, not creating a new one. However, in your code no such name exists, so you're not actually referencing anything.
first create your "database" somewhere global
clt = dict(map(lambda x:x.split(" ",1),open("preciosEsp.txt","r+"))
now you can acess it anywhere with
clt.get(nClient)
next calcular should return the values you want
def calcular():
...
precio = clt.get(nClient)
return [precio,nClient,...]
then you would store the returned values (or do something with them as soon as they are returned )
Here is my code (sorry for the messy code):
def main():
pass
if __name__ == '__main__':
main()
from easygui import *
import time
import os
import random
import sys
##multenterbox(msg='Fill in values for the fields.', title=' ', fields=(), values=())
msg = "Enter your personal information"
title = "Credit Card Application"
fieldNames = ["First name",'Last name','email',"Street Address","City","State","ZipCode",'phone','phone 2)']
fieldValues = [] # we start with blanks for the values
fieldValues = multenterbox(msg,title, fieldNames)
# make sure that none of the fields was left blank
def make(x):
xys = x,".acc"
xyzasd = str(xys)
tf = open(xyzasd,'a+')
tf.writelines(lifes)
tf.writelines("\n")
tf.writelines("credits = 0")
tf.close
def add(x):
nl = "\n"
acc = ".acc"
xy = x + acc
exyz = xy
xyz = exyz
xxx = str(xyz)
tf = open('accounts.dat',"a+")
tf.writelines(nl)
tf.writelines(xxx)
tf.close
while 1:
if fieldValues == None: break
errmsg = ""
for i in range(len(fieldNames)-1):
if fieldValues[i].strip() == "":
errmsg += ('"%s" is a required field.\n\n' % fieldNames[i])
if errmsg == "":
break # no problems found
fieldValues = multenterbox(errmsg, title, fieldNames, fieldValues)
names = enterbox(msg= ('confirm FIRST name and the FIRST LETTER of the persons LAST name'))
##txt = "acc"
##na = str(name)
##name = (names)
life = ( str(fieldValues))
lifes = life,'\n'
herro = ("Reply was: %s" % str(fieldValues))
correct = buttonbox(msg=(herro,'\n is that correct'),choices = ('yes','no','cancel'))
if correct == "yes":
make(names)
add(names)
elif correct == "no":
os.system('openacc.py')
time.sleep(0.5)
sys.exit()
else:
os.system('cellocakes-main.py')
sys.exit()
os.system('cellocakes-main.py')
I don't know what the problem is also I am sorry about how sloppy it was programmed I have a white board to help me out still new to programming (I'm only 13) sorry. Personally I think the issue is in the def add area's syntax but because I am still new I don't see the issue personally I am hoping to have a more experienced programmer help me out.
This is an answer not directly answering your question.
Alas, comment fields are STILL not capable to hold formatted code, so I choose this way.
def main():
pass
if __name__ == '__main__':
main()
This is a nice coding pattern, but used by you in a useless way.
It is supposed to prevent executing of the stuff if it is imported as a module and not executed as a script.
Nevertheless, it is not bad to use it always, but then put your code inside the main() function instead of adding it below.
fieldNames = ["First name",'Last name','email',"Street Address","City","State","ZipCode",'phone','phone 2)']
There is a ) too much.
fieldValues = [] # we start with blanks for the values
fieldValues = multenterbox(msg,title, fieldNames)
The second line makes the first one useless, as you don't use fieldValues in-between.
It would be different if you expected multenterbox() to fail and would want [] as a default value.
def make(x):
xys = x,".acc"
xyzasd = str(xys)
tf = open(xyzasd,'a+')
tf.writelines(lifes)
tf.writelines("\n")
tf.writelines("credits = 0")
tf.close
You was already told about this: x, ".acc" creates a tuple, not a string. To create a string, use x + ".acc".
Besides, your close call is no call, because it is missing the (). This one just references the function and ignores the value.
A better way to write this would be (please name your variables appropriately)
with open(xyzs, 'a+') as tf:
tf.writelines(lifes)
tf.writelines("\n")
tf.writelines("credits = 0")
The with statement automatically closes the file, even if an error occurs.
Besides, you use writelines() wrong: it is supposed to take a sequence of strings and write each element to the file. As it doesn't add newlines in-between, the result looks the same,. but in your case, it writes each byte separately, making it a little bit more inefficient.
Additionally, you access the global variable lifes from within the function. You should only do such things if it is absolutely necessary.
def add(x):
Here the same remarks hold as above, plus
xy = x + acc
exyz = xy
xyz = exyz
xxx = str(xyz)
why that? Just use xy; the two assignments do nothing useful and the str() call is useless as well, as you already have a string.
for i in range(len(fieldNames)-1):
if fieldValues[i].strip() == "":
errmsg += ('"%s" is a required field.\n\n' % fieldNames[i])
Better:
for name, value in zip(fieldNames, fieldValues):
if not value.strip(): # means: empty
errmsg += '"%s" is a required field.\n\n' % name
Then:
life = ( str(fieldValues))
makes a string from a list.
lifes = life,'\n'
makes a tuple from these 2 strings.
os.system('openacc.py')
os.system('cellocakes-main.py')
Please don't use os.system(); it is deprecated. Better use the subprocess module.
The problem of the question is here:
# assign the tuple (x, ".acc") to xys
xys = x,".acc"
# now xyzasd is the tuple converted to a string, thus
# making the name of your file into '("content of x", ".acc")'
xyzasd = str(xys)
# and open file named thus
tf = open(xyzasd,'a+')
What you wanted to do is:
# use proper variable and function names!
def make_account(account):
filename = account + '.acc'
the_file = open(filename, 'a+')
....
On the other hand there are other problems with your code, for example the
def main():
pass
if __name__ == '__main__':
main()
is utterly useless.