I want to use a while loop to initialize class objects with a simple incremented naming convention. The goal is to be able to scale the number of class objects at will and have the program generate the names automatically. (ex. h1...h100...h1000...) Each h1,h2,h3... being its own instance.
Here is my first attempt... have been unable to find a good example.
class Korker(object):
def __init__(self,ident,roo):
self.ident = ident
self.roo = roo
b = 1
hwinit = 'h'
hwstart = 0
while b <= 10:
showit = 'h' + str(b)
print(showit) #showit seems to generate just fine as demonstrated by print
str(showit) == Korker("test",2) #this is the line that fails
b += 1
The errors I get range from a string error to a cannot use function type error.... Any help would be greatly appreciated.
If you want to generate a number of objects, why not simply put them in an array / hash where they can be looked up later on:
objects = {}
for b in range(1,11):
objects['h'+str(b)] = Korker("test", 2)
# then access like this:
objects['h3']
Of course there are ways to make the names available locally, but that's not a very good idea unless you know why you need it (via globals() and locals()).
Variables are names that point to objects that hold data. You are attempting to stick data into the variable names. That's the wrong way around.
instead of h1 to h1000, just call the variable h, and make it a list. Then you get h[0] to h[999].
Slightly different solution to viraptor's: use a list.
h = []
for i in range(10):
h.append(Korker("test",2))
In fact, you can even do it on one line with a list comprehension:
h = [Korker("test", 2) for i in range(10)]
Then you can get at them with h[0], h[1] etc.
Related
I have a bit of python code that's set to run on a schedule. (I think my problem is the same as if it were within a loop.)
Let's say that in its most basic form, the code snippet looks something like this:
A = 1
B = 2
renameMe = A + B
Let's say the scheduler runs the same snippet of code every 5 minutes. The values of variables A & B are different each time the code is run, but the operation renameMe = A + B is always the same.
The values for A & B are grabbed out of a dataframe that's updated every 5 minutes, so I don't know what they are in advance, but if I need to do something with them beforehand instead of assigning them to A & B right away, I can.
I recently found out that for other things to work, I need to be able to rename the variable renameMe every time that snippet of code runs. In other words, I want the variable's name to be renameMe1 the first time the code snippet runs, then renameMe2 when it runs 5 minutes later, and so on.
It doesn't really matter in which way the variable's name changes (ints, strs, whatever) as long as I'm able to find out what the new variable name is, and use it elsewhere.
Do NOT use a variable variable name, you will have problems, use a container:
a list:
# first time
container = []
# each loop/run
container.append(A+B)
## last value
container[-1]
a dictionary:
# first time
container = {}
# each loop/run
container['new_id'] = A+B
# access arbitrary value
container['my_previous_id']
If you need persistence, use a flat file or a database.
I think it is suitable to use a class so that setattr can be used:
class newVal:
def __init__(self):
self.n = 1
def addVal(self, a, b):
setattr(self, f”val{self.n}”, a+b)
self.n += 1
Values = newVal()
Values.addVal(a, b)
Values.val1 would now be assigned
I aggree with Mozway when saying variables names are likely to cause problems, but this is also something you could strictly manage.
globals() stores all variables names and values in the form of a collection of 2-tuples, like this one :
dict_items([('__name__', '__main__'), ..., ('thisName', 'renaMe1'), ('renaMe18', 10)])
So you should register your new variable name but not forget to delete the previous one in order to avoid overloading.
If you follow a natural law of equal births and deaths, you will avoid overpopulation.
I propose you this bunch of code (with comments inside) :
basename = 'renaMe'
def varUpdate():
# Get previous variable name
thisName = [i for i, j in globals().items() if i[:len(basename)] == basename][0]
# Define the new variable name
newName = basename + '%d'%sum([int(thisName[len(basename):]), 1])
# Register the new variable name
globals()[newName] = globals()[thisName]
# Delete previous variable name from global
del globals()[thisName]
def process(i):
# Isolate from process content for readibility
varUpdate()
# PROCESS BELOW
# ....
newVar = [i for i, j in globals().items() if i[:len(basename)] == basename][0]
print(newVar, " : ", globals()[newVar])
# With this for` loop we simulate 4 entries in process
for i in range(4):
### we enter in the process
process(i)
Test in the shell
First restart your shell and let's suppose we have at the beginning renaMe12 = 12 :
>>> renaMe12 = 12
>>> Proposed Script ...
Result
Variable increments it's proper name at each iteration.
renaMe13 : 12
renaMe14 : 12
renaMe15 : 12
renaMe16 : 12
If you check in the shell now, you could see at the end of iteration, renaMe12 to renaMe15 no longer exist.
Only the variable renaMe16 exists with value 12.
>>> renaMe16
12
>>>> renaMe15
Retraçage (dernier appel le plus récent) :
Shell Python, prompt 4, line 1
builtins.NameError: name 'renaMe15' is not defined
Conclusion
This discussion is just for the sake of experimentation, but if I were you I would do my possible to avoid such code complexification unless it's necessary.
I agree Mozway when thinking you should avoid pain headaches...
Hi, I'm F2C
It is easy to write a program in python that makes 1, 2, 3 objects.
But how do you make 100, 200, 300 objects, all with different names?
I tried to use a counting variable to get the name, e.g. object1, object2, object3,...
But when I try to use that variable's value as a name, I just get an object with a name of the variable, NOT it's value.
So the question is:
How to name an object with a value of variable?
Here is an example:
I want to make 100 python turtles with names T1, T2, T3,...,T99, T100 using a simple loop.
import turtle
n = "T"
for i in range(1, 100):
n = "T" + str(i)
n = turtle.Turtle() # Here is the problem
Instead, I only get 1 turtle named "n". I also tried with string formatting, but it also didn't go well.
I know this this question might seem unnecessary, but I am just curious if it is possible or is there some better solution.
You can simply create list of Objects eg:
n = []
for i in range(1,100):
n.append(turtle.Turtle())
Read more about it here: https://www.geeksforgeeks.org/how-to-create-a-list-of-object-in-python-class/
Within pytorch, creating layers, can be semi automated, thus the reason for using a for loop.
One of the main issues is that these layers cannot stored within a list or dictionary or else back propagation will not work.
Thus the reason for a work around.
Within the object, assigning new self attributes
How do i replace this
self.res1 = 1
self.res2 = 2
self.res3 = 3
with this
for i in range(2):
res_name = 'res'+str(i+1)
self.res_name = i
Now that i have created objects this way, how can I access them in the same way. For example, if we assume self.res_name is now an object?
for i in range(2):
res_name = 'res'+str(i+1)
out = self.res_name(out)
You probably should use a dict or list instead. But if you really want this for some reason, you can try setattr(x, attr, 'magic').
Thus, in your case, it's
for i in range(1, 4):
res_name = 'res' + str(i)
setattr(self, res_name, i)
See this related question for more info.
I want to create a structure, as we do in C, in python. I have tried to use namedtuple() for this. However, I can not update the values of variables I have described inside the custom structure.
Here is how i declared it:
from collections import namedtuple as nt
Struct = nt('Struct','all left right bottom top near far')
And this is what i am trying to do in a method :
class codeClip:
def compOutCode(x,y,z,xmin,xmax,ymin,ymax,zmin,zmax):
code = Struct(0,0,0,0,0,0,0)
if(y > ymax):
code.top = 1
code.all += code.top
elif(y < ymin):
code.bottom = 1
return code
However it is giving this error:
code.top = 1
AttributeError: can't set attribute
What should I do? Pardon me, I am fairly new in python, so still getting used to all of these.
You may use the _replace() method.
Instead of code.top = 1, you can update values as follows.
code = code._replace(top = 1)
Please note, named tuples are immutable, so you cannot manipulate them. If you want something mutable, you can use recordtype.
Reference: https://stackoverflow.com/a/31253184/5352399
I am trying to understand what does this class
class undo:
def __init__(self, ss):
self.ss = ss
In my head it should simply put the value of ss uniquely in the variables i decide to use,but when I'm using it it rewrites all the variables, as if it was shared.
sum_expenses[100][0] = 100
sum_expenses[99][2] = 99
s = 1
a = [0 for i in range(100)]
a[s] = undo(sum_expenses)
output(a[1].ss)
sum_expenses[100][0] = 0
b = undo(sum_expenses)
print " "
print b.ss
print " "
sum_expenses[99][2] = 1
a[2] = undo(sum_expenses)
print a[2].ss
I do not understand why it overwrites all the variables with the current values of sum_expense, when I try to put it individually so that I can use the past values of sum_expenses.
Thank you and have a good day!
It happens because you're giving __init__ a reference to the list. If you change the list somewhere else, the reference in .ss still points to the same list, so the changes are visible there, too.
You could copy the list, since it's 2D try deepcopy.
Everytime you call this function it overrides reference to thr whole array ss, changing it to the new one you just passed to the constructor.
You can also create this array within the class and pass indexes and value to it like so:
undo.add(index1,index2,value)
Or you can make another variable ss_old and have make the function return that variable before you set it to a new value.