My function works on its own but not callable from class - python

I've made a class as follow:
class Plugins:
def __init__(self):
pass
def voter_rep(self, loc, start_header, end_header):
self.loc = loc
ocr_xml = AbbyyXML(loc)
xml_doc = XMLDoc(ocr_xml, CONSTANTS)
xml_doc.split_words("", False)
self.start_header = start_header
self.end_header = end_header
header_pages = xml_doc.se_page(start_header, end_header)
## and stuff
voter_dict = {'Voter':[], 'Record_Key':[], 'Comments':[]}
## and stuff
return voter_dict, rep_dict
if I run the method function on its own and outside of the class it works totally fine, namely if I write the function as:
def voter_rep(loc, start_header, end_header):
ocr_xml = AbbyyXML(loc)
xml_doc = XMLDoc(ocr_xml, CONSTANTS)
xml_doc.split_words("", False)
header_pages = xml_doc.se_page(start_header, end_header)
## and stuff
voter_dict = {'Voter':[], 'Record_Key':[], 'Comments':[]}
## and stuff
return voter_dict, rep_dict
in the function alone I get rid of self and will just have voter_rep(loc, start_header, end_header) but when I want to call it from the class I do plugins.voter_rep(loc, start_header, end_header) which does not work, and it returns:
NameError: name 'plugins' is not defined
I wonder why is it that my function works on its own but not callable from the class?

You can do
plugins = Plugins()
loc = #some val
start_header = #some val
end_header = #some val
plugins.voter_rep(loc, start_header, end_header)
As the error message shows, you are using small 'p' instead of capital. Also since it is not a static function, so it is not good to call it via class name.

Plugins.voter_rep(loc, start_header, end_header)
Take note of the capital letter.

Related

assign function w/multiple parameters to a variable —both inside a Python class

While my code works, I'd like to clean it a bit.
I've built a couple of functions based on thethe File().trashUntrash method,
and I've done the same for other methods in the class I'm working on:
class File():
def__init__(self):
self.this = this
self.that = that
def trashUntrash(self, fileId, bool):
return file.update(fileId, isTrashed=bool)
#these two are wrappers for self.trashUntrash:
trash = lambda self, fileId: self.trashUntrash(fileId, True)
untrash = lambda self, fileId: self.trashUntrash(fileId, False)
#these other lambdas correspond to other methods:
fileTitle = lambda self, id: self.fileInfo(prop="title", spreadsheetId=id)
fileIds = lambda self, id: self.fileInfo(prop="fileId", spreadsheetId=id)
addPage = lambda self, id, title: self.action(i=0, ssId=id, title=title)
delPage = lambda self, id, pageId: self.action(i=1, ssId=id, pageId=pageId)
renameFile = lambda self, id, pageId, title: self.action(i=2, id=id ...)
So I tried assigning the method to variables that I'd then use in the rest of my code:
trash = self.trashUntrash(fileId, True)
untrash = self.trashUntrash(fileId, False)
# and so on...
... as it looks shorter and more easily readable (my goal). But... I get NameError: name 'self' is not defined. Removing self (which of course, doesn't make sense):
trash = trashUntrash(fileId, True)
untrash = trashUntrash(fileId, False)
# etc.
... will on the other hand, produce NameError: name 'fileId' is not defined. If on the other hand, I simply state:
trash = self.trashUntrash
untrash = self.trashUntrash
# etc... doing this one DOES work BUT
# w/o a chance to pass params, which defeats my intent.
... I'll get no errors, but I'll have to manually pass args, including the ones I'm using as default, making the function-to-variable assignment pointless.
So my question: Is it possible to assign a method along with its params to a variable inside a class, and how would you do it?
BTW, I'm using Python 3.10.8 (Nov 1 2022, GCC 12.2.0 on Linux); thank you in advance!
I've already gotten the job done via lambda functions;
however, they get quite lengthy as I'm using
multiple positional and keyword args. I'd like a way to make these assignments shorter to read.
In the class use partialmethod to define your shortcut. If a further shortcut is needed you can assign the partial method to a local variable:
from functools import partialmethod
class File():
def trash_untrash(self, file_id, is_trashed):
print(f"{file_id = }, {is_trashed = }")
trash = partialmethod(trash_untrash, is_trashed=True)
f = File()
f.trash(file_id=10)
trash = f.trash
trash(file_id=10)
Output:
file_id = 10, is_trashed = True
file_id = 10, is_trashed = True

python, calling a method from another class

I am trying to call the sum_method function from my evaluation class to my main one, however I run into many errors. I want to use the new_data as the data parameter of my sum_method function.
evaluation class:
class evaluation():
def __init__(self, data):
self.data = data
def sum_method(self):
montant_init = self.data.loc[self.data['Initiateur'] == 'Glovoapp', 'Montant (centimes)'].sum()
print(montant_init)
main class:
class main(evaluation):
new_data.to_csv("transactions.csv", index=False)
self.data = new_data
def call_sum(self, new_data):
init_eval = evaluation.sum_method(self=new_data)
print(init_eval)
init_evalobj = main()
init_evalobj.call_sum()
if you use the method in your inherence class just use self
so:
init_eval = self.sum_method()
the self argument is passed in python automaticly as first parameter
update
you also should return a value:
def sum_method(self):
montant_init = self.data.loc[self.data['Initiateur'] == 'Glovoapp', 'Montant (centimes)'].sum()
print(montant_init)
return montant_init
I'd suggest making some changes to the both classes, to encapsulate the .data member variable in the base class. My preference would also be to separate out the calculation from the display, so leave all the print statements in the call_sum() function.
class evaluation:
def __init__(self, data):
self.data = data
def sum_method(self):
montant_init = self.data.loc[self.data['Initiateur'] == 'Glovoapp', 'Montant (centimes)'].sum()
return montant_init
class main(evaluation):
def __init__(self):
# Reduce csv content to what's needed for analysis
data_csv = pd.read_csv('transactions.csv')
# --> removing unnecessary data
new_data = data_csv[['Opération', 'Initiateur', 'Montant (centimes)', 'Monnaie',
'Date', 'Résultat', 'Compte marchand', 'Adresse IP Acheteur', 'Marque de carte']]
# --> saving changes...
new_data.to_csv("transactions.csv", index=False)
super().__init__(new_data) //Initialize the base class
def call_sum(self):
print('Glovoapp "montant" generated')
init_eval = self.sum_method() //Call the method from the base class
print(init_eval)

Function as class attribute

I am writing a class where I would like to pass function as a class attribute and later use it, like that:
class Nevronska_mreza:
def __init__(self, st_vhodni, st_skriti, st_izhod, prenosna_funkcija=pf.sigmoid):
self.mreza = []
self.st_vhodni = st_vhodni
self.st_skriti = st_skriti
self.st_izhodni = st_izhod
self.prenosna_funckija = prenosna_funkcija
self.mreza.append([{'utezi': [random() for i in range(st_vhodni + 1)]} for j in range(st_skriti)])
self.mreza.append([{'utezi': [random() for i in range(st_skriti + 1)]} for j in range(st_izhod)])
def razsirjanje_naprej(self, vhod):
for sloj in self.mreza:
nov_vhod = []
for nevron in sloj:
nevron['izhod'] = self.prenosna_funkcija(self.aktivacijska_funkcija(nevron['utezi'], vhod))
nov_vhod.append(nevron['izhod'])
vhod = nov_vhod
return vhod
but it seems like this isn't the right way, I get the following error:
AttributeError: 'Nevronska_mreza' object has no attribute 'prenosna_funkcija'
Is it possible to do something like that?
Yes you can pass a function around as an argument however you have made a couple of mistakes.
Firstly you have used the word function, although not a reserved word it should be avoided as a name of an entity such as a variable.
Secordly you have used an optional parameter before mandatory parameters which will cause an error such as:
File "test.py", line 5
def __init__(self, function=fun1, data1, data2):
^
SyntaxError: non-default argument follows default argument
Thirdly when calling the method you have not specified the scope, the function name is in the self scope of the object.
Taking all of these into account the following is working code
def fun1(x):
return x+1
class A:
def __init__(self, data1, data2, fn=fun1):
self.fn = fn
self.data1 = data1
self.data2 = data2
def some_method(self):
y = self.fn(self.data1)
print(y)
b = A(1, 2, fun1)
b.some_method()
After posting your full code I can see that you currently have self.prenosna_funckija instead of prenosna_funkcija in the following line:
self.prenosna_funckija = prenosna_funkcija
This would explain the attribute error as when you are calling self.prenosna_funkcija it genuinely does not exist.
You're close:
def fun1(x):
return x+1
class A:
def __init__(self, function=fun1, data1=None, data2=None):
self.function = function
self.data1 = data1
self.data2 = data2
def some_method(self):
y = self.function(self.data1)
return y
a = A(data1 = 41)
result = a.some_method()
print(result)
prints
42

Python function call within a property of a class

I am trying to use the "setx" function of a Property in a Class to do some processing of date information that I get from excel. I have a few of my own functions that do the data processing which I tested outside the class, and they worked just fine. But when I move them into the class they suddenly become invisible unless I use the self. instance first. When I use the self.My_xldate_as_tuple() method I get an error:
My_xldate_as_tuple() takes 1 positional argument but 2 were given
Even though the code is EXACTLY what i used outside the class before and it worked.
Before moving into the Property Set block, I was doing the processing of date data outside of the class and setting the variables from outside of the class. That gets clunky when I have about 15 different operations that are all based on when the NumDates Property change. I'm showing shortened versions of both the working set of code and the non-working set of code. What is going on with the self. call that changes how the function takes inputs?
Broken Code:
class XLDataClass(object):
_NumDates = []
TupDates = []
def getNumDates(self): return self._NumDates
def setNumDates(self, value):
self._NumDates = value
self.TupDates = list(map(self.My_xldate_as_tuple,value)) #Error here
#This version doesn't work either, since it can't find My_xldate_as_tuple anymore
self.TupDates = list(map(My_xldate_as_tuple,value))
def delNumDates(self):del self._NumDates
NumDates = property(getNumDates,setNumDates,delNumDates,"Ordinal Dates")
#exact copy of the My_xldate_as_tuple function that works outside the class
def My_xldate_as_tuple(Date):
return xlrd.xldate_as_tuple(Date,1)
#Other code and functions here
#end XlDataClass
def GetExcelData(filename,rowNum,titleCol):
csv = np.genfromtxt(filename, delimiter= ",")
NumDates = deque(csv[rowNum,:])
if titleCol == True:
NumDates.popleft()
return NumDates
#Setup
filedir = "C:/Users/blahblahblah"
filename = filedir + "/SamplePandL.csv"
xlData = XLDataClass()
#Put csv data into xlData object
xlData.NumDates= GetExcelData(filename,0,1)
Working Code:
class XLDataClass(object):
NumDates = []
TupDates = []
#Other code and functions here
#end XlDataClass
#exact copy of the same function outside of the class, which works here
def My_xldate_as_tuple(Date):
return xlrd.xldate_as_tuple(Date,1)
def GetExcelData(filename,rowNum,titleCol):
csv = np.genfromtxt(filename, delimiter= ",")
NumDates = deque(csv[rowNum,:])
if titleCol == True:
NumDates.popleft()
return NumDates
#Setup
filedir = "C:/Users/blahblahblah"
filename = filedir + "/SamplePandL.csv"
xlData = XLDataClass()
#Put csv data into xlData object
xlData.NumDates = GetExcelData(filename,0,1)
#same call to the function that was inside the Setx Property of the class, but it works here.
xlData.TupDates = list(map(self.My_xldate_as_tuple,value))
Instance methods in Python require an explicit self in the argument list. Inside the class, you need to write your method definition like:
def My_xldate_as_tuple(self, Date):

How to grab variable from an import module

I am trying to get the variable - clipFileInfo in which it came from an import module. I run the following code:
from Library import libmaya
publishClip = libmaya.ClipPublish()
clip = publishClip.getClip()
print clip.clipFileInfo
But it will give me an error saying that # AttributeError: 'list' object has no attribute 'clipFileInfo' #
This is the portion of code that I am deriving from
class ClipPublish( lib.ClipPublish ):
...
...
def __getclipFileInfo( self ):
'''
Return list of dicts to pass through to writeClip function
'''
clipFileInfo = []
for rig in self.rigList.Rigs():
actor = rig.pop( 'actor', None )
if actor:
clipFileInfo = {}
clipFileInfo['actor'] = actor
clipFileInfo['rig'] = rig
clipFileInfo['name'] = self.__unit.get( rig['name'] )
clipFileInfo.append( clipFileInfo )
return clipFileInfo
def getClip( self ):
clipFileInfo = self.__getclipFileInfo()
if clipFileInfo:
start = self.frameRange.startFrame()
end = self.frameRange.endFrame()
clipFile = writeC.writeclip( clipFileInfo, start, end )
if clipFile == None:
return None
return clipFile[0] if self.isSingle() else clipFile
return []
Is this possible to do so in the first place?
It looks like you are trying to pull a local variable out of a function. Unless the function returns this local variable, it is not possible.
Instead, as the comment says, you should call publishClip.__getclipFileInfo() to get the value of that variable, since that function does return it.
To be more explicit, try the following code.
from Library import libmaya
publishClip = libmaya.ClipPublish()
info = publishClip.__getclipFileInfo()
print info

Categories

Resources