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
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())
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
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.
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
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().