Performing Calculation on Objects in python class - python

I have a class in python that will need to perform calculations on objects which get their data from lists that loop though and add a new row from a csv every time.
How can I call the objects defined in __init__() into the calcA(), calcB(), calcC() methods to perform a calculation for every row stored in it and then write the results back into the object defined in Calculation without changing the data already stored in __init__?
I will then use the objects from __init__ and Calculation to write to columns in a csv
class CreateObjects():
def __init__(self, OjectID, ObjectPrice, ObjectNum, Objectzone, ObjectTicket, Multiplier):
self.OjectID= OjectID
self.ObjectPrice= ObjectPrice
self.ObjectTicket= ObjectTicket
self.ObjectNum= ObjectNum
self.Objectzone= Objectzone
self.Multiplier = Multiplier
def Calculation(self, A, B, C):
self.A = A
self.B = B
self.C = C
def calcA():
pass
def calcB():
pass
def calcC():
pass

Assuming that calcA() is a method, then it should have a first parameter (called self by convention). You can use that to access all properties / attributes of the class instance.
For example:
class CreateObjects:
...
def calcA(self):
# this will allways work, because '__init__()' is allways
# called before this method
print(self.OjectID)
# this will only work if the method 'Calculation()' was called
# before this, because otherwise 'A' will not be defined yet
print(self.A)

Related

Value Changed in Class B calls function in Class A to update object of class A

I want to call a function from a class A inside another class B. However, it should be called for an object of A. I mean if I have something like this:
class A:
def __init__(self, ....):
self.valuechanged=False
# do something
objectfromb=B()
self.somearray.append(objectfromb)
def updateevent(self):
self.valuechanged=True
# do some things if update event triggered
class B:
def __init__(self,...):
self.somevalue=0
self.someothervalue=1
# do something
def updatesomevalue(self,somenewvalue):
self.somevalue=somenewvalue
# !!! HERE SHOULD BE A CALL TO CLASS A FUNCTION updateevent
And in my code I use the classes like this:
a=A()
Then i would have a list somearray in a (a.somearray) which contains an object of B. So if I want to update this object B with:
a.somearray[0].updatesomevalue(10)
Then there should not only be a new value for a.somearray[0].somevalue but also the function update event of class A should trigger changing a. How can I do that?
There are two ways I can think of to achieve this without invoking any special magic.
The first is to have objects of type B know what object A they belong to so that they can call updateevent on it. This isn't a way I'm generally a fan of as there's extra admin work to do when moving instances of B between instances of A and such. If that's not a concern then it may be the best way. You'd do that something like this (with a method on A to create a B and set the correct parent for convenience):
class A:
valuechanged=False
somearray=[]
def add_b(self):
b = B(self)
somearray.append(b)
return b
def updateevent(self):
self.valuechanged=True
class B:
somevalue=0
someothervalue=1
def __init__(self, parent):
self.parent = parent
def updatesomevalue(self,somenewvalue):
self.somevalue=somenewvalue
self.parent.updateevent()
The second is to provide a method on A that does both tasks. This is only suitable if 1) you know A will always contains instances of B and only B and 2) B's interface is relatively small (to avoid providing lots of methods of this type on A). You would implement this as something like:
class A:
valuechanged=False
somearray=[]
def updatesomevalue(self, index, new_value):
somearray[index].updatesomevalue(new_value)
self.updateevent()
def updateevent(self):
self.valuechanged=True
class B:
somevalue=0
someothervalue=1
def updatesomevalue(self,somenewvalue):
self.somevalue=somenewvalue
Something I haven't addressed is that somearray, somevalue, etc are all being created as class attributes in your example (i.e. they will be shared among all instances, instead of each instance having its own ones). This is likely not what you wanted.

How do I find the input parameters of an instantiated Python class object?

My goal is to reload the class object using __init__(...) but with an extra argument. So I am trying to get the original class object input parameters to perform this reloading. However, some input arguments of the original class object is not saved as an attribute: example: self.a = a. How do I perform such reloading by finding the input parameters that is not saved?
Example code:
class TestOnly:
def __init__(self, a, b, c=None):
self.a = a
self.c = c
test = TestOnly(1, 2)
# I want to know b=2 here:
test = test.__init__(a=test.a, b=something_i_want_to_know, c=123)
How can I find out b=2 programmatically?
You can never access the b variable as you have not stored it in the class.
class TestOnly:
def __init__(self, a, b, c=None):
self.a = a
self.c = c
test = TestOnly(1, 2)
Your new shiny TestOnly object is now stored in the test variable.
You can then call
print (test.a)
print(test.c)
As you stored them with self.a =a etc
You can't however access b as you didn't save it into the object.
And after init has been called the b variable will be discarded.
Don't use
Test.__init__()
Although it may be possible (I'm not sure) , it's not the way to use it as TestOnly() does this already.

Instance variable as function of other instance variables

Is it possible to define an instance variable in a class as a function of another? I haven't gotten it to work unless you redefine the "function instance variable" all the time.
Basically you could have a scenario where you have one instance variable that is a list of integers, and want to have the sum of these as an instance variable, that automatically redefines every time the list is updated.
Is this possible?
class Example:
list_variable = []
sum_variable = sum(list_variable)
def __init__(self, list_variable):
self.list_variable = list_variable
return
This will result in sum_variable = 0 unless you change it.
I understand that this is far from a major issue, you could either define sum_variable as a method or redefine it every time you change list_variable, I'm just wondering if it's possible to skip those things/steps.
Python offers the property decorator for a syntatically identical use of your example:
class Example:
list_variable = []
def __init__(self, list_variable):
self.list_variable = list_variable
return
#property
def sum_variable(self):
return sum(self.list_variable)
e = Example(list_variable=[10, 20, 30])
e.sum_variable # returns 60

Python: Getting value from calling function

In Python, is there a simple way for an invoked function to get a value from the calling function/class ? I'm not sure if I'm phrasing that right, but I'm trying to do something like this:
class MainSection(object):
def function(self):
self.var = 47 # arbitrary variable
self.secondaryObject = secondClass() # Create object of second class
self.secondaryObject.secondFunction(3) # call function in that object
and
class secondClass(object):
def secondFunction(self, input)
output = input + self.var # calculate value based on function parameter AND variable from calling function
return output
#Access self.var from MainSection
This might be my lack of knowledge about Python, but I'm having a hard time finding a clear answer here. Is the best way to do that just passing the variable I want in as another second parameter to the second class?
These are in separate files, if that makes a difference.
Is the best way to do that just passing the variable I want in as another second parameter to the second class?
Yes, especially if there's only a transient relationship between the objects:
class secondClass(object):
def secondFunction(self, input, var_from_caller)
output = input + var_from_caller # calculate value based on function parameter AND variable from calling function
return output
You can even pass around the whole object if you like:
class secondClass(object):
def secondFunction(self, input, calling_object)
output = input + calling_object.var # calculate value based on function parameter AND variable from calling function
return output
If the relationship is more permanent, you could consider storing references to the related objects in instance variables:
class MainSection(object):
def function(self):
self.var = 47 # arbitrary variable
self.secondaryObject = secondClass(self) # Create object of second class
self.secondaryObject.secondFunction(3) # call function in that object
...
class secondClass(object):
def __init__(self, my_friend):
self.related_object = my_friend
def secondFunction(self, input)
output = input + self.related_object.var # calculate value based on function parameter AND variable from calling function
return output
#Access self.var from MainSection

Identify the elements returned by different processes

Consider the following situation:
class A:
def __init__(self):
self.b_list = []
def add_element(b)
self.b_list.append(b)
class B:
def __init__(self,x):
self.x = x
class C:
def __init__(self,a,other_data):
self.a = a
def find_new_b(self):
....
def solve(c):
return c.find_new_b()
Each instance of class A has a list of instances of class B, that are added in an incremental way.
I need to iterate over all the instances of class A and find for each of them a new element of class B.
I'm using multiprocessing to do that
list_of_c_elements = [...]
pool = multiprocessing.Pool()
results = pool.map(solve, list_of_c_elements)
The problem
In results I have a list of results and I would like to understand of which instance of class A the new instance of class B belongs. Each instance of class B is generic, and I would like to keep the two classes decoupled.
Considered solution
Change solve() to:
def solve(c):
return (c.a, c.find_new_b())
I have to compare all the elements of class A I have with the one returned (very inefficient).
I cannot do something like:
for output in results:
output[0].add_element(output[1])
since the instance of class A returned is another instance.
Is there a more efficient way to achieve my goal?
C could additionally hold id(a) in a member and you can generate an index dictionary {id(a): a} if necessary. Be aware that all calls of id() must of course happen in the main process to produce usable results.

Categories

Resources