How to pass parameters into __init__ function - python

I am starting my journey in python. I want to create a program that will convert my xlsx file into an sql file and then load data into a data base.
I want to create class that will have two parameters:
ex - will open xlsx workbook
sh - will open sheet from ex with correct index
This is initial version (for now I am just printing rows):
class XToSql():
def __init__(self, ex = xlrd.open_workbook('ex1.xlsx'), sh = ex.sheet_by_index(0)):
self.ex = ex
self.sh = sh
def modify(self):
for i in str((self.sh.nrows-1)):
a = 1
print(self.sh.row_values(a))
a += 1
a1 = XToSql()
a1.modify()
In the __init__ function, this line is marked with red color: sh = ex.sheet_by_index(0) -> and this error appears after Run:
def __init__(self, ex = xlrd.open_workbook('ex1.xlsx'), sh = ex.sheet_by_index(0)):
NameError: name 'ex' is not defined
Any ideas what I am doing wrong?

In __init__'s parameter list, ex has not been evaluated yet so sh = ex.sheet_by_index(0)) is throwing the NameError. This happens when the class object is being created.
You can do a couple of things. One reason to write a class is so you can reuse it, so maybe the class should only except the filepath as an argument.
class XToSql():
def __init__(self, ex_file):
self.ex = xlrd.open_workbook(ex_file)
self.sh = self.ex.sheet_by_index(0)
def modify(self):
for i in str(self.sh.nrows - 1):
a = 1
print(self.sh.row_values(a))
a += 1
Maybe you should be able to specify the sheet to process
class XToSql():
def __init__(self, ex_file, sheet=0):
self.ex = xlrd.open_workbook(ex_file)
self.sh = self.ex.sheet_by_index(sheet))
def modify(self):
for i in str(self.sh.nrows - 1):
a = 1
print(self.sh.row_values(a))
a += 1
And use it like this
a = XToSql(ex_file='ex1.xlsx', sheet=0)

ex is not available until inside the body of the __init__ method. You cannot access an argument of the method outside the body of the method.
You would need to do something like the following:
class XToSql:
def __init__(self, ex, sh=None):
self.ex = ex
if sh is None:
sh = ex.sheet_by_index(0)
self.sh = sh
And then call it like this:
a1 = XToSql(xlrd.open_workbook('ex1.xlsx'))

Related

Run and return value of class function inside __init__ Python Class Constructor

Hello Stackoverflow folks,...
I hope this questions is not already answered.
After half a day of googeling I did resign myself to asking a question here.
My problem is the following:
I want to create a class which takes some information and processes this information:
#Klassendefinition für eine Instanz von Rohdaten
class raw_data():
def __init__(self, filename_rawdata, filename_metadata,
file_format, path, category, df_raw, df_meta):
self.filename_rawdata = filename_rawdata
self.filename_metadata = filename_metadata
self.file_format = file_format
self.path = path
self.category = category
self.df_raw = getDF(self.filename_rawdata)
self.df_meta = getDF(self.filename_metadata)
# generator
def parse(self, path):
g = gzip.open(path, 'rb')
for l in g:
yield eval(l)
# function that returns a pandas dataframe with the data
def getDF(self, filename):
i = 0
df = {}
for d in self.parse(filename):
df[i] = d
i += 1
return pd.DataFrame.from_dict(df, orient='index')
Now I have a problem with the init method, I would like to run the class method below on default when the class in instantiated, but I somehow cannot manage to get this working. I have seen several other posts here like [Calling a class function inside of __init__ [1]: Python 3: Calling a class function inside of __init__
but I am still not able to do it. The first question did work for me, but I would like to call the instance variable after the constructor ran.
I tried this:
class raw_data():
def __init__(self, filename_rawdata, filename_metadata,
file_format, path, category):
self.filename_rawdata = filename_rawdata
self.filename_metadata = filename_metadata
self.file_format = file_format
self.path = path
self.category = category
getDF(self.filename_rawdata)
getDF(self.filename_metadata)
# generator
def parse(self, path):
g = gzip.open(path, 'rb')
for l in g:
yield eval(l)
# function that returns a pandas dataframe with the data
def getDF(self, filename):
i = 0
df = {}
for d in self.parse(filename):
df[i] = d
i += 1
return pd.DataFrame.from_dict(df, orient='index')
But I get an error because getDF is not defined (obviously)..
I hope this questions is not silly by any means. I need to do it that way, because afterwards I want to run like 50-60 instance calls and I do not want to repeat like Instance.getDF() ... for every instance, but rather would like to have it called directly.
All you need to so is call getDF like any other method, using self as the object on which it should be invoked.
self.df_raw = self.getDF(self.filename_rawdata)
That said, this class could be greatly simplified by making it a dataclass.
from dataclasses import dataclass
#dataclass
class RawData:
filename_rawdata: str
filename_metadata: str
path: str
category: str
def __post_init__(self):
self.df_raw = self.getDF(self.filename_rawdata)
self.df_meta = self.getDF(self.filename_metadata)
#staticmethod
def parse(path):
with gzip.open(path, 'rb') as g:
yield from map(eval, g)
#staticmethod
def getDF(filename):
return pd.DataFrame.from_records(enumerate(RawData.parse(filename)))
The auto-generated __init__ method will set the four defined attributes for you. __post_init__ will be called after __init__, giving you the opportunity to call getDF on the two given file names.

How to close a file inside another function of the class in Python?

I got a function run(self) and inside that function I was to open a file. I then want to close that file inside another function, reset(self).
This is my class:
class Heater (threading.Thread):
STATE_IDLE = "IDLE"
STATE_RUNNING = "RUNNING"
def __init__(self, simulate=False, time_step=config.sensor_time_wait):
threading.Thread.__init__(self)
self.daemon = True
self.simulate = simulate
self.time_step = time_step
self.reset()
if simulate:
self.temp_sensor = TempSensorSimulate(self, 0.5, self.time_step)
if sensor_available:
self.temp_sensor = TempSensorReal(self.time_step)
else:
self.temp_sensor = TempSensorSimulate(self,
self.time_step,
self.time_step)
self.temp_sensor.start()
self.start()
def reset(self):
self.profile = None
self.start_time = 0
self.runtime = 0
self.totaltime = 0
self.target = 0
def run(self):
now = datetime.datetime.now()
self.name = os.path.join('/storedata/store', "Date_" + now.strftime("%Y-%m-%d") + ".txt")
self.file = open(name, 'a')
self.file.write(now.strftime("%Y-%m-%d"))
reset()
would I just put self.file = self.run.file.close in reset(self) to achieve this?
I would do the following:
def __init__(self, simulate=False, time_step=config.sensor_time_wait):
self.file = None
now there is an attribute called file in your class. Set to None. Now
def __reset(self):
if self.file:
self.file.close()
self.file = None
that should do it ! Note that __reset is safe to call when the file isn't opened, since the file attribute exists and is None (closing an already closed file doesn't do anything, but still, it's clearer)
Note that this design only is interesting if you're using self.file somewhere else. Else don't define any member just do:
name = os.path.join(... // your code used "self.name" for some reason
with open(name, 'a') as file:
file.write(now.strftime("%Y-%m-%d"))
As a general rule, define class members only when necessary, and local variables anywhere else.

Python class recording attributes without specifying self ?

I have a question regarding a Python class I use in Blender. Basically, I wonder how the class works because some attributes are recorded without me specifically writing self.value = something. Here's the code:
class DialogOperator(bpy.types.Operator):
bl_idname = "object.dialog_operator"
bl_label = "Save/Load animation"
saving = bpy.props.BoolProperty(name="Save ? Else load.")
path_to_anim = bpy.props.StringProperty(name="Path to folder")
anim_name = bpy.props.StringProperty(name="Animation name:")
# path_to_anim += "/home/mehdi/Blender/Scripts/"
def execute(self, context):
# print('This is execute with: Saving: {} Name:{}'.format(self.saving, self.path_to_anim))
if self.saving:
self.launch_save()
message = 'Animation {} saved at {}'.format(self.anim_name, self.path_to_anim)
else:
self.launch_load()
message = 'Animation {} loaded'.format(self.anim_name)
self.report({'INFO'}, message)
return {'FINISHED'}
def invoke(self, context, event):
wm = context.window_manager
return wm.invoke_props_dialog(self)
def launch_load(self):
full_path = self.path_to_anim + self.anim_name
target_armature = Humanoid(bpy.data.objects['Armature'])
load_all(full_path, target_armature, 'LastLoaded')
def launch_save(self):
full_path = self.path_to_anim + self.anim_name
source_armature = Humanoid(bpy.data.objects['Armature'])
curves = source_armature.get_curves()
save_all(curves, source_armature,full_path)
Now, how come saving, path_to_anim and anim_name are considered as attributes (I'm able to call them in execute() and launch()) even though I did not write self.saving = saving
Thanks !
This is because saving,path_to_anim and anim_name are class attributes. They are defined for the class and not for a particular instance. They are shared among the instances. Here is a link for further explanation class-instance-attributes-python

Python UNO on LibreOffice Calc, rehoming a cursor

LibreOffice 5.3, python 3.53, VOID Linux
This is more of an uno question than a python question. The code below does a simple update of 3 cells. 3 buttons configured on the sheet calling dowriteonce() dowritetwice() and dowritethrice(), and they all update and work like you might expect writing numbers and text to selected cells.
Where the problem comes in, is that when a cell is edited in the UI by a user, any subsequent update of that cell by means of executing the function is blocked. So simply clicking cell C4 in the calc UI, prevents the writethrice() function from updating cell C4. If I delete the content and click another cell in the UI, say C5, then everything works normally again and C4 updates when the button is clicked.
What I would like to do is relocate the UI edit-cursor to an unused cell prior to execution in order to prevent this. User copy-paste is going to leave the active cursor in unpredictable places and that will bork calculations if I can't isolate the cursor.
So the question is, how do I move the UI edit cursor to a named cell via the UNO API, with Python? Or if it is easier, just deactivate it temporarily.
Python:
import socket
import sys
import re
import uno
import unohelper
class ODSCursor(unohelper.Base):
# predeclare class properties
ctx=None
desktop=None
model=None
activesheet=None
counter=0
scooby="Scooby"
# import namespaces
def __init__(self):
import socket
import uno
import unohelper
import sys
import re
# initialize uno handle only once and get the first sheet
#classmethod
def sheet1(cls,*args):
if cls.activesheet is not None:
return (cls.activesheet)
cls.ctx = uno.getComponentContext()
cls.desktop = cls.ctx.ServiceManager.createInstanceWithContext("com.sun.star.frame.Desktop", cls.ctx)
cls.model = cls.desktop.getCurrentComponent()
# cls.activesheet = cls.model.Sheets.getByName("Sheet1")
cls.activesheet = cls.model.Sheets.getByIndex(0)
return (cls.activesheet)
#classmethod
def writeonce(self,*args):
self.counter += 1
cell_b1 = self.activesheet.getCellRangeByName("B1")
cell_b1.String = self.counter
#classmethod
def writetwice(self,*args):
self.counter += 1
cell_b2 = self.activesheet.getCellRangeByName("B2")
cell_b2.String = self.counter
#classmethod
def writescooby(self,*args):
cell_c4 = self.activesheet.getCellRangeByName("C4")
cell_c4.String = self.scooby
### BUTTON BOUND FUNCTIONS ###
def dowriteonce(*args):
Odc = ODSCursor() # create the object
Odc.sheet1()
Odc.writeonce()
def dowritetwice(*args):
Odc = ODSCursor() # create the object
Odc.sheet1()
Odc.writetwice()
def dowritethrice(*args):
Odc = ODSCursor() # create the object
Odc.sheet1()
Odc.writescooby()
In the following code, cells are deselected before changing the values, then selected again. This way, cells can be modified even when left in edit mode by the user.
There also seems to be some confusion about Python class methods and variables, so I changed those parts as well.
import uno
import unohelper
SCOOBY = "Scooby"
class ODSCursor(unohelper.Base):
def __init__(self):
self.ctx = None
self.desktop = None
self.document = None
self.controller = None
self.sheet = None
self.counter = 0
def sheet1(self):
"""Initialize uno handle only once and get the first sheet."""
if self.sheet is not None:
return self.sheet
self.ctx = uno.getComponentContext()
self.desktop = self.ctx.ServiceManager.createInstanceWithContext(
"com.sun.star.frame.Desktop", self.ctx)
self.document = self.desktop.getCurrentComponent()
self.controller = self.document.getCurrentController()
self.sheet = self.controller.getActiveSheet()
return self.sheet
def writeonce(self):
self.writeval("B1", self.inc())
def writetwice(self):
self.writeval("B2", self.inc())
def writescooby(self):
self.writeval("C4", SCOOBY)
def writeval(self, address, value):
self.deselect()
cell = self.sheet.getCellRangeByName(address)
cell.String = value
self.controller.select(cell)
def deselect(self):
"""Select cell A1, then select nothing."""
cell_a1 = self.sheet.getCellByPosition(0, 0)
self.controller.select(cell_a1)
emptyRanges = self.document.createInstance(
"com.sun.star.sheet.SheetCellRanges")
self.controller.select(emptyRanges)
def inc(self):
"""Increment the counter and return the value."""
self.counter += 1
return self.counter
odsc = ODSCursor()
### BUTTON BOUND FUNCTIONS ###
def dowriteonce(dummy_oEvent):
odsc.sheet1()
odsc.writeonce()
def dowritetwice(dummy_oEvent):
odsc.sheet1()
odsc.writetwice()
def dowritethrice(dummy_oEvent):
odsc.sheet1()
odsc.writescooby()

Python - How to create more than one object in a single class?

I am trying to instantiate more then one object in a single class. I am trying to instantiate them in the class instead of the main function. I am new to python, so trying to learn. Example, I have this piece of code, my input file is a text file with all strings. I want to instantiate the object when my regex in region is true and/or sub-region is true. I want to instantiate them there and NOT in the main function. How can I do that? since every time I run my code I can have zero or one or two objects:
class Tracker(object):
def __init__(self):
self.region = ""
self.subregion = ""
def updateRegion(self,input):
if self.endingRegion:
self.region = ""
if self.endingSubRegion:
self.subregion = ""
#Regions
temp = re.search(r'CLI Command: \'(.*)\'', input)
if temp:
self.region = temp.group(1)
print self.region
#SubRegions
temp = re.search(r'Equipped Type \(if different\)',input)
if temp:
self.subregion = "Equipped Type"
print self.subregion
def main():
with open ('/home/thamer/TS_ncren202_XRS-20_20150624_12.0.R6.txt','r') as f:
tracker = Tracker()
for line in f:
tracker.updateRegion(line)
region = tracker.getRegion()
subregion = tracker.getSubRegion()
if __name__ == '__main__':
main()

Categories