python instantiate a nested class - python

I read several post about the nested class, but this mechanism is still not clear for me.
Basically what I want to do is define a class (to solve ordinary differential equation in which I define one class for each order of accuracy )
Here's the class :
class AdamsBashforth(AdamsMethods):
class _2nd(AdamsMethods):
startup = False
def __init__(self, dydt : Rhs, filename :str = None , salve : bool = True ):
self.file = filename
self.save = save
super().__init__(dydt)
def solve(self):
self.time , self.u = self.dydt.createArray()
u[1] = rungekutta.RK2.step(self.dydt.f, time[0], u[0], self.dt)
for i in range(1,len(self.time)-1):
self.u[i+1] = u[i] + self.dt/2*(3*self.dydt.f(self.time[i],self.u[i])-self.dydt.f(self.time[i-1],self.u[i-1]))
AdamsBashforth._2nd.solved = True
if self.file != None:
super().write2file()
if self.save:
return self.time,self.u
def plot(self):
if AdamsBashforth._2nd.solved:
super().plot('Sys ODE solution using Adams-Bashforth 2nd order','time [s]','y(t)')
else:
print("Unsolved problem, call `solve` method before")
#classmethod
def step(cls, func , t : np.float , u : np.float, dt ):
def f(ti,ui):
return np.array([function(ti,ui) for function in func])
if AdamsBashforth._2nd.startup == False:
#print ("AB start-up")
AdamsBashforth.u1 = rungekutta.RK2.step(func,t,u,dt)
AdamsBashforth.startup = True
unext = AdamsBashforth.u1 + dt/2.*(3.*f(t+dt,AdamsBashforth.u1) - f(t,u))
AdamsBashforth.u1 = u
return unext
Here's the way that I would really like to do is to call:
problem = AdamsBashforth._2nd(dydt)
but i receive an error that says that adamsbashforth has no member _2nd
so I've try to doing so .. but still the same message :
class AdamsBashforth(AdamsMethods):
def __init__(self, dydt, filename :str = None , salve : bool = True):
self._2nd = self._2nd(dydt,filename,salve)
def solve(self):
pass
class _2nd(AdamsMethods):
What is the right way in order to obtain a call like the first (problem = AdamsBashforth._2nd(dydt))
and using the class _2nd
EDIT
class AdamsBashforth(AdamsMethods):
def __init__(self, dydt, filename :str = None , save : bool = True):
self._2nd = AdamsBashforth._2nd(dydt,filename,save)
def solve(self):
pass
class _2nd(AdamsMethods):
startup = False
solved = False
def __init__(self, dydt : Rhs, filename :str = None , save : bool = True ):
self.file = filename
self.save = save
super().__init__(dydt)
def solve(self):
self.time , self.u = self.dydt.createArray()
self.u[1] = rungekutta.RK2.step(self.dydt.f, self.time[0], self.u[0], self.dt)
for i in range(1,len(self.time)-1):
self.u[i+1] = u[i] + self.dt/2*(3*self.dydt.f(self.time[i],self.u[i])-self.dydt.f(self.time[i-1],self.u[i-1]))
_2nd.solved = True
if self.file != None:
super().write2file()
if self.save:
return self.time,self.u
def plot(self):
if AdamsBashforth._2nd.solved:
super().plot('Sys ODE solution using Adams-Bashforth 2nd order','time [s]','y(t)')
else:
print("Unsolved problem, call `solve` method before")
#classmethod
def step(cls, func , t : np.float , u : np.float, dt ):
def f(ti,ui):
return np.array([function(ti,ui) for function in func])
if AdamsBashforth._2nd.startup == False:
#print ("AB start-up")
AdamsBashforth.u1 = rungekutta.RK2.step(func,t,u,dt)
AdamsBashforth.startup = True
unext = AdamsBashforth.u1 + dt/2.*(3.*f(t+dt,AdamsBashforth.u1) - f(t,u))
AdamsBashforth.u1 = u
return unext
calling in this way :
ab2_p1 = adamsmethods.AdamsBashforth(problem1, 'ab2_1.dat')
ab2t,ab2u = ab2_p1._2nd.solve()
ab2_p1.plot()
looks that work .. but I don't know why ... and I don't know if is it the correct way !!
but I have still problem in order to call the classmethod for example :
u = adamsmethods.AdamsBashforth._2nd.step(func0,t,u,dt)
doesn't work :
Traceback (most recent call last):
File "drive.py", line 287, in <module>
main()
File "drive.py", line 149, in main
u = adamsmethods.AdamsBashforth._2nd.step(func0,t,u,dt)
AttributeError: type object '_2nd' has no attribute 'step'
------------------------------------------------------------

Related

Python: Save specific method in object

How can I assign a specific method to an object in Python that is not part of the class.
I want to have a class that executes a specific method that is not part of the class but is part of the file.
I want to reduce if-else loops with this.
class RangeStrategie(object):
x0 = 0
x1 = 0
name = ""
functions = ???
def __init__(self,x0,x1,name,func):
self.x0 = x0
self.x1 = x1
self.name = name
self.functions = func
def execute(self, y):
if self.x0 <= y and y <= self.x1:
print("--> Execute {} Option {}-{} mit {}".format(self.name,self.x0,self.x1,y))
self.functions()
It is possible?
def pse():
print("Test")
if __name__ == '__main__':
RangeStrategie(1,9,"Einer",pse())

Python - Parent method don't acess the value of variable children

Hi I'm having a problem in this classes I created the parent class extracao_nia with the method aplica_extracao for having the similar part of the execution that I use in others class and the diferent part is in the transform method definined in the children class
but I'm having an issue that the variables that I defined as list() are Null variable when I execute the code:
AttributeError: 'NoneType' object has no attribute 'append'
class extracao_nia:
def __init__(self, d=1, h=1, m=15):
self._data_base = "database"
self.UM_DIA = datetime.timedelta(days=d)
self.UMA_HORA = datetime.timedelta(hours=h)
self.INTERVALO = datetime.timedelta(minutes=m)
#property
def data_base(self):
return self._data_base
def aplica_extracao(self, SQL):
fim_intervalo = self.inicio + self.INTERVALO#
pbar = self.cria_prog_bar(SQL)#
while (fim_intervalo <= self.FIM):#
self.connector.execute(SQL,(self.inicio.strftime('%Y-%m-%d %H:%M'),fim_intervalo.strftime('%Y-%m-%d %H:%M')))#
for log in self.connector:#
self.transforma(log)
self.inicio = fim_intervalo
fim_intervalo = self.inicio + self.INTERVALO
class usuarios_unicos(extracao_nia):
def __init__(self, d=1, h=1, m=15, file='nodes.json'):
self._data_base = "database"
self.UM_DIA = datetime.timedelta(days=d)
self.UMA_HORA = datetime.timedelta(hours=h)
self.INTERVALO = datetime.timedelta(minutes=m)
self.file = file
self.ids = list()
self.nodes = list()
self.list_cpf = list()
def transforma(self, log):
context = json.loads(log[0])['context']
output = json.loads(log[0])['output']
try:
nr_cpf = context['dadosDinamicos']['nrCpf']
conversation_id = context['conversation_id']
nodes_visited = output['output_watson']['nodes_visited']
i = self.ids.index(conversation_id)
atual = len(self.nodes[i])
novo = len(nodes_visited)
if novo > atual:
nodes[i] = nodes_visited
except KeyError:
pass
except ValueError:
self.ids.append(conversation_id)
self.nodes = self.nodes.append(nodes_visited)
self.list_cpf = self.list_cpf.append(nr_cpf)
list.append returns None since it is an in-place operation, so
self.nodes = self.nodes.append(nodes_visited)
will result in self.nodes being assigned None. Instead you can just use
self.nodes += nodes_visited

Calling multiple functions from within function

I am trying to call a function from within a function, and the former calls more functions etc.
import ROOT as root
import sys, math
class SFs():
def __init__(self):
self.get_EfficiencyData = None
self.get_EfficiencyMC = None
self.get_ScaleFactor = None
self.eff_dataH = None
self.eff_mcH = None
self.get_ScaleFactor = None
self.get_EfficiencyMC = None
def ScaleFactor(self,inputRootFile):
self.eff_dataH = root.std.map("string", root.TGraphAsymmErrors)()
self.eff_mcH = root.std.map("string", root.TGraphAsymmErrors)()
EtaBins=["Lt0p9", "0p9to1p2","1p2to2p1","Gt2p1"]
fileIn = root.TFile(inputRootFile,"read")
HistoBaseName = "Label"
etaBinsH = fileIn.Get("Bins")
# etaLabel, GraphName
nEtaBins = int(etaBinsH.GetNbinsX())
for iBin in range (0, nEtaBins):
etaLabel = EtaBins[iBin]
GraphName = HistoBaseName+etaLabel+"_Data"
print GraphName,etaLabel
self.eff_dataH[etaLabel]=fileIn.Get(str(GraphName))
self.eff_mcH[etaLabel]=fileIn.Get("histo")
print self.eff_mcH[etaLabel].GetXaxis().GetNbins()
print self.eff_mcH[etaLabel].GetX()[5]
self.get_ScaleFactor(46.8,2.0)
def get_ScaleFactor(self,pt, eta):
efficiency_mc = get_EfficiencyMC(pt, eta)
if efficiency_mc != 0.:
SF = 1/float(efficiency_mc)
else:
SF=1.
return SF
def get_EfficiencyMC(self,pt, eta):
label = FindEtaLabel(eta,"mc")
# label= "Lt0p9"
binNumber = etaBinsH.GetXaxis().FindFixBin(eta)
label = etaBinsH.GetXaxis().GetBinLabel(binNumber)
ptbin = FindPtBin(eff_mcH, label, pt)
Eta = math.fabs(eta)
print "eff_mcH ==================",eff_mcH,binNumber,label,ptbin
# ptbin=10
if ptbin == -99: eff =1
else: eff= eff_mcH[label].GetY()[ptbin-1]
if eff > 1.: eff = -1
if eff < 0: eff = 0.
print "inside eff_mc",eff
return eff
sf = SFs()
sf.ScaleFactor("Muon_IsoMu27.root")
I want to call the get_ScaleFactor() which in turn calls the get_EfficiencyMC() etc, but I once trying calling the former, I get TypeError: 'NoneType' object is not callable
in your class init you define:
self.get_EfficiencyMC = None
and later define a function (i.e. class method)
def get_EfficiencyMC(self,pt, eta):
when you create an instance of the class, the init part is executed shadowing the class method. Just either remove it from the init, or change the method name.

NameError: name '_length' is not defined

I'm using python3 and when trying to run the following code, I'm facing the error:
NameError: name '_length' is not defined
The code itself:
class OFPHELLO(GenericStruct):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._length = self.get_size()
_msg_type = OFPType.OFPT_HELLO
_build_order = ('header', 'x')
header = OFPHeader(type = _msg_type, length = _length)
x = UBInt8()
The problem is the _length variable that I'm passing in OFPHeader, the value of which is computed in GenericStruct. How can I compute the _length variable inside the OFPHELLO class and use it as parameter in the OFPHeader class?
Following the GenericStruct code:
class GenericStruct(object):
def __init__(self, **kwargs):
for a in kwargs:
try:
field = getattr(self, a)
field.value = kwargs[a]
except AttributeError:
raise OFPException("Attribute error: %s" % a)
def build(self):
hexa = ""
for field in self._build_order:
hexa += getattr(self, field).build()
return hexa
def parse(self, buff):
begin = 0
for field in self._build_order:
size = getattr(self, field).get_size()
getattr(self,field).parse(buff, offset=begin)
begin += size
def get_size(self):
tot = 0
for field in self._build_order:
tot += getattr(self, field).get_size()
return tot
- how have you defined (GenericStruct)
- header = OFPHeader(type = _msg_type, length = _lenght)
- correct the spelling to _length
-- and please post the entire code next time

Unable to use values from a class into another class

I am trying to grab the values from a class and use that particular value into another class. However I keep getting this error - AttributeError: 'CustomNodeTranslator' object has no attribute 'start'
Basically I am trying to get/transfer the values of self.start and self.end to be used into the ChanFileExporter class
I am not exactly sure why it is not working but when I applied this similar method in another portion of the code, it is working fine.
Any advises are greatly appreciated!
class CustomNodeTranslator(OpenMayaMPx.MPxFileTranslator):
def __init__(self):
OpenMayaMPx.MPxFileTranslator.__init__(self)
def haveWriteMethod(self):
return True
def haveReadMethod(self):
return True
def filter(self):
return "*.chan"
def defaultExtension(self):
return "chan"
def writer( self, fileObject, optionString, accessMode ):
self.start = []
self.end = []
for opt in filter(None, optionString.split(';')):
optSplit = opt.split('=')
if optSplit[1] == '0':
startAnimation = cmds.findKeyframe(which='first')
endAnimation = cmds.findKeyframe(which='last')
self.start = startAnimation
self.end = endAnimation
class ChanFileExporter():
def __init__(self, transform, startAnimation, endAnimation, cameraObj):
self.fileExport = []
testClass = CustomNodeTranslator()
mayaGlobal = OpenMaya.MGlobal()
mayaGlobal.viewFrame(OpenMaya.MTime(1))
startAnimation = testClass.start
endAnimation = testClass.end
for i in range(int(startAnimation), int(endAnimation + 1)):
...
...
The first time you see start or end in CustomNodeTranslator is in the writer() method.
self.start = []
self.end = []
It is bad practice to add attributes outside of __init__(); and the reason why it fails for you is because you are referring to attributes that do not yet exist since they are created only after you call writer().

Categories