Getting all possible value combinations - python

For an automatic test thing, I have a class with ~15 parameters. I want to automatically generate instances of the class for every possible value combination. For instance, if the class was defined like so:
class meep():
def __init__(self):
self.par1 = 0 # can be in range {0-3}
self.par2 = 1 # can be in range {1-2}
self.par3 = a # can be in range {a-c}
What is the most efficient to get instances of it with all possible value combinations? (IE
inst1=(par1=0,par2=1,par3=a),
inst2=(par1=0,par2=1,par3=b),
inst3=(par1=0,par2=1,par3=c),
inst4=(par1=1,par2=1,par3=a),
inst5=(par1=1,par2=1,par3=b),
inst6=(par1=1,par2=1,par3=c),
etc.)

itertools.product()

Related

A class for spin up and down particles?

So I have a bunch of particles which can be of two kinds let's say "up" and "down". I am new to python but I know that this segregation can be done with the help of a class.
Let's say I have a list:
T=np.linspace(0,1,1000)
I want each element of this list to be either one of the two particles but I am not sure if I should create two classes with one "kind" each or a single class with two "instances" and assign each element an instance.
In the end, what I want to do is randomly distribute this property of being "up" and "down" over the list T.
There is not enough info. You most likely don't want 2 instances when dealing with 1000 items - each item should be probably represented by separate instance of a class. But that doesn't mean that having 2 classes is a way to go.
Are the particles relatively similiar and besides the difference of a single property they have the same behaviour? If so, I'd go for single class, 1000 instances and storing the up/down property in some instance attribute.
EDIT:
This is how I would personally implement this with for the current requirements in question:
class Particle:
def __init__(self, posInit, momInit, spin):
self.posInit = posInit
self.momInit = momInit
self.spin = spin
def momOfT(self, t):
return self.momInit*(math.cos(t))+self.posInit*(math.sin(t))
def posOfT(self, t):
return self.posInit*(math.cos(t))-self.momInit*(math.sin(t))
T = [Particle(posInit = i, momInit = 1-i, spin = random.choice(["up", "down"])) for i in np.linspace(0, 1, 1001)]
print([T[0].posOfT(i) for i in np.linspace(0, 3.1415*2, 1000)])

How to map dataframe rows into a custom object?

I am trying to map the individual rows of a dataframe into a custom object. The dataframe consists of multiple molecules that interact with a specific target. Additionally, multiple molecular descriptors are given. A slice is given below:
Now i need to map each instance into a Molecule object defined as something like this:
class Molecule:
allDescriptorKeys = []
def __init__(self, smiles, target, values):
self.smiles = smiles
self.target = target
self.d = {}
for i in range(len(Molecule.allDescriptorKeys)):
self.d[Molecule.allDescriptorKeys[i]] = values[i]
Where the allDescriptorsKeys class variable is set from outside the class using
def initdescriptorkeys(df):
Molecule.allDescriptorKeys = df.keys().values
Now I need a class function readMolDescriptors that reads in the molecule descriptors of a single molecule(row/instance). To use it later on in an external method to loop over the whole dataframe .I guess I need something like this:
def readMolDescriptors(self, index):
smiles = df.iloc[index]["SMILES"]
target = df.iloc[index]["Target"]
values = df.iloc[index][2:-1]
newMolecule = Molecule(smiles, target, values)
return newMolecule
But of course this is not a class function since the df is defined outside the class. I have a hard time wrapping my head around this, probably easy, problem. Hope someone can help.
It seems that you want to build a class from which you build a new instance for each row of the dataframe, and after that you want to get rid of the dataframe and play with those Molecule instances alone. Consider this:
class Molecule:
def __init__(self, data_row):
''' data_row: pd.Series. '''
self.smiles = data_row['SMILES']
# more self.xxx = data_row['xxx']
self.d = data_row.to_dict()
With this you can create an object of Molecule using a data row. For example,
molecules = [Molecule(data_row) for index, data_row in df.iterrows()]
To access a certain descriptor (e.g. nAT) value from the first molecule, you may do
print(molecules[0].d['nAT'])
although you can choose to define more dedicated method with the class to handle access like that.
Ofcourse, to build something like readMolDescriptors, below is my version.
def build_molecule_from_dataframe(df, index):
return Molecule(df.loc[index])

How to get class instance variables, python

I would like to get the names of __init__ parameters and modify them when the code runs. My class looks like this:
class Sample:
def __init__ (self,indicators:dict):
self.names = []
self.returns = 0.0
for k,v in indicators.items():
setattr(self, k, v)
self.names.append(k)
The input of this class is a random choice of items from a lis; then I assign those random items to a dictionary with integer values.
indicatorsList =["SMA", "WMA", "EMA", "STOCHASTIC", "MACD", "HIGHEST_HIGH",
"HIGHEST_LOW", "HIGHEST_CLOSE", "LOWEST_HIGH", "LOWEST_LOW",
"LOWEST_CLOSE", "ATR", "LINGRES", "RSI", "WRSI", "ROC",
"DAY", "MONTH"]
# initializing the value of n
n = random.randint(2,int(math.ceil(len(indicatorsList)/2)))
randomIndList = n * [None]
for i in range(n):
choice = random.choice(indicatorsList)
randomIndList[i] = choice
...
...
sample = Sample(randDict)
Problem is, I don't know the names of these parameters in __init__, and I need to modify them later, for example like this:
sample.sma = random.randint(0, maxVal)
But I don't know if the object will have sma, or ema, or any other attribute, because of the way they're assigned randomly.
First of all, this code:
sample.sma = random.randint(0, maxVal)
will work, even if sample doesn't have an sma attribute. It will create one. Try it yourself and see.
But as you specified in your comment that you only want to modify attributes that already exist, that won't help in this case.
What you could do, with your existing class definition, is to loop over the names attribute you've already defined.
for name in sample.names:
setattr(sample, name, random.randint(0, maxVal))
However, you've basically reinvented a dictionary here, so why not redefine your class to directly use a dictionary?
class Sample:
def __init__(self, indicators:dict):
self.indicators = indicators
Now you no longer need dynamic setattr or getattr lookups. They're simply keys and values:
for key in sample.indicators:
sample.indicators[key] = random.randint(0, maxVal)
(This also means you don't need the separate names attribute.)

Should a class to have several attributes or one attribute as dictionary with many keys, Python3

I have class for calculating temperatures of an object at different positions, based on ambient temperature. I have two ways of implementation. In BodyA, the temperature of each position is an attribute of the class; while in BodyB, there is an attribute pos_t, which is a dict, and the temperature of each position is just a key-value pair in the dict.
class BodyA:
def __init__(self, ambient_temperature)
self.amb_t = ambient_temperature
self.pos1_t = self.amb_t + 1
self.pos2_t = self.amb_t * 2
self.pos3_t = self.pos1_t + self.pos2_t - 5
class BodyB:
def __init__(self, ambient_temperature)
self.amb_t = ambient_temperature
self.pos_t = dict()
self.pos_t['pos1'] = self.amb_t + 1
self.pos_t['pos2'] = self.amb_t * 2
self.pos_t['pos3'] = self.pos_t['pos1'] + self.pos_t['pos2'] - 5
In practical case, there are up-to 10 positions, and I want to build child-class from it. And some child-classes do not have certain positions. For example, pos2 can be missing in some child.
Could you please let me know, which design is better in terms of OOP and efficiency. Thanks.
A data structure to store some custom identifiers that may or may exist calls clearly for a dict. As class attributes are also stored in an internal dict, the first approach can be used too, but to have pratical manipulation without explicit hand writing the members will require different code. I suspect performance will not matter. If you find it matters, maybe a redesign of the data structure that does not use classes at all will do, as object creation processing time may be relevant then.

Python: Iterating over predetermined conditions within conditions

I need to iterate over a number of attributes inside an object. Each attribute is initialized as None and over the course of the program each will store a separate object. There are 16 attributes that I need to iterate over and the condition is that the attributes will store objects in a predetermined sequence. For example, if attribute 10 is empty, then attributes 11 to 16 will also be empty, therefore I will not need to iterate past any empty attributes. My initial result was to use 'if' statements for each attribute like this:
Class Object1:
def __init__(self):
self.attribute1=None
self.attribute2=None
self.attribute3=None
self.attribute4=None
...
def repeating_function(self):
if self.attribute1!=None:
self.attribute1.attribute=Callback1
if self.attribute2!=None:
self.attribute2.attribute=Callback2
if self.attribute3!=None:
self.attribute3.attribute=Callback3
...
But, because of the sequence in which the attributes store objects, I ended up with this:
class Object1:
def __init__(self):
self.attribute1=None
self.attribute2=None
self.attribute3=None
self.attribute4=None
self.attribute5=None
def repeating_function(self):
if self.attribute1!=None:
self.attribute1.attribute=Callback1
if self.attribute2!=None:
self.attribute2.attribute=Callback2
if self.attribute3!=None:
self.attribute3.attribute=Callback3
...
Basically, my question is: if the second example is more efficient at iterating over the non-empty attributes. Because I'm adding conditions inside conditions in the second example, I'm not sure which method is more efficient.
You should use a list instead of separate attributes:
class MyClass(object):
def __init__(self):
self.attributes = []
With this,
to add an attribute, use self.attributes.append(...);
to find out how many (non-None) attributes there are, use len(self.attributes);
to refer to the final non-None attribute, use self.attributes[-1];
and so on.

Categories

Resources