How to separate a python class that needs access the kv file - python

So I have a class in my python file that I want to seperate from the main python file because I will need to modify it a couple time and use it in the main one. However since the class needs access to the kivy file to read the ids I cannot seperate this class from the main one without loading the kv file twice which messes everything up. How can I basically make this class importable?
class RightSide(BoxLayout):
order_size = []
overlay = StringProperty('Current Order will be displayed here')
tabname = parameter_length
iterator = 0
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.orientation = 'vertical'
for i in range(len(menu)):
self.add_widget(Skeleton())
def tally(self):
global OID
order_size = self.order_size
print(OID)
OID = OID + 1
print(OID)
rightside = kv.ids.one.two.three.newlay.rightside
for skel in rightside.children:
if isinstance(skel, Skeleton):
if self.iterator > len(menu)-1:
self.iterator = 0
order_size.clear()
self.tabname[self.iterator] = skel.drink_name, skel.ids.label_id.text
self.iterator = self.iterator + 1
order_size.insert(0, skel.ids.label_id.text)
order_size.insert(0, OID)
self.tabname.reverse()
self.tabname.insert(0, OID)
makeitastring = ''.join(map(str, self.tabname))
self.overlay = makeitastring
con = sql.connect(host='xxxxxx', user='root', password='xxxxxxx.', database='new_schema')
cur = con.cursor()
cur.execute(query, order_size)
con.commit()
con.close()
def clean(self):
rightside = kv.ids.one.two.three.newlay.rightside
for skel in rightside.children:
if isinstance(skel, Skeleton):
skel.ids.label_id.text = '0'
skel.count = 0
kv = Builder.load_file("b.kv")

So the solution was to declare the kv variable in a seperate py file using "import new_file.py" and accessing it via "new_file.kv"

Related

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

How to pass parameters into __init__ function

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'))

Python Script Connecting To MySQL Database - Code ran as procedural script, fails after OOP refactor

I have a script that can run a number of different reports, based on what input it receives via the command line. All reports read from a database and return the results as a Pandas Dataframe object.
Here is the super-class, (omitting a large number of property getter and setter functions):
import mysql.connector
import pandas as p
import config
class Report(object):
_connection = None
_cursor = None
def __init__(self):
self._user = config.user
self._password = config.password
self._host = config.host
self._database = config.database
self._port = config.port
self._body_text = "Hello,\n\nPlease find attached these reports:\n\n"
self._connection = mysql.connector.connect(user=self._user, password=self._password, db=self._database,
host=self._host, port=self._port)
self._cursor = self._connection.cursor()
#property
def user(self):
return self._user
#user.setter
def user(self, value):
self._user = value
. . .
#property
def body_text(self):
return self._body_text
#body_text.setter
def body_text(self, value):
self._body_text = value
def append_body_text(self, value):
self._body_text += value
def get_data(self, server_cursor, query, columns):
server_cursor.execute(self, query)
results = server_cursor.fetchall()
data = p.DataFrame(data=results, columns=[columns])
return data
def get_today(self):
return self.today
def close(self):
self._connection_web.close()
self._connection_raw.close()
#staticmethod
def insert_variables_into_sql_statement(query, external_data):
final_query = query % external_data
return final_query
#staticmethod
def create_string_from_column(serial):
created_list = serial.tolist()
string = ', '.join(map(str, created_list))
return string
#staticmethod
def write_to_csv(data_frame, file_name):
data_frame.to_csv(config.baseDirectory + file_name, sep=',', index=False)
def generate_report(self):
data = self.get_data(self._cursor_web, self._query, self._columns)
self.write_to_csv(data, self._filename)
self.close()
Here is how my subclasses are structured:
class ExampleReport(Report):
def __init__(self):
Report.__init__(self)
self._query = """
SELECT
u.first_name AS 'First Name',
u.last_name AS 'Last Name'
FROM users AS u
"""
self._columns = "'FirstName', 'LastName'"
self._filename = "example_report.csv"
self.append_body_text("* All users")
In my main method I call the method like this:
report = Reports.ExampleReport()
report.generate_report()
When I do this, I get the following error:
AttributeError: 'ExampleReport' object has no attribute 'encode'
My database connections worked without a problem when it was terribly constructed procedural code (a working version is currently in production). It has broken now that I've tried to make it object oriented. Does anyone have any idea what I've done wrong?
EDIT: SOLVED MY OWN PROBLEM! In the get_data function in the super-class, the second line contained an erroneous self argument passed into server_cursor.execute(query) line. Once it was taken out, the error goes away.
SOLVED MY OWN PROBLEM! In the get_data function in the super-class, the second line contained an erroneous self argument passed into server_cursor.execute(query) line. Once it was taken out, the error goes away.

Learning how to use the deferred library

I'm trying code nearly identical to the example from the manual to enable a download counter but I get an exception:
File "/media/Lexar/montao/wwwblob/handler.py", line 117, in FileInfo
download_count = db.IntegerProperty(required=True, count=0) TypeError: init() got an unexpected keyword argument 'count'
Here's the code I try to run:
from google.appengine.ext import deferred
from google.appengine.runtime import DeadlineExceededError
class Mapper(object):
# Subclasses should replace this with a model class (eg, model.Person).
KIND = None
# Subclasses can replace this with a list of (property, value) tuples to filter by.
FILTERS = []
def __init__(self):
self.to_put = []
self.to_delete = []
def map(self, entity):
"""Updates a single entity.
Implementers should return a tuple containing two iterables (to_update, to_delete).
"""
return ([], [])
def finish(self):
"""Called when the mapper has finished, to allow for any final work to be done."""
pass
def get_query(self):
"""Returns a query over the specified kind, with any appropriate filters applied."""
q = self.KIND.all()
for (prop, value) in self.FILTERS:
q.filter('%s =' % prop, value)
q.order('__key__')
return q
def run(self, batch_size=100):
"""Starts the mapper running."""
self._continue(None, batch_size)
def _batch_write(self):
"""Writes updates and deletes entities in a batch."""
if self.to_put:
db.put(self.to_put)
self.to_put = []
if self.to_delete:
db.delete(self.to_delete)
self.to_delete = []
def _continue(self, start_key, batch_size):
q = self.get_query()
# If we're resuming, pick up where we left off last time.
if start_key:
q.filter('__key__ >', start_key)
# Keep updating records until we run out of time.
try:
# Steps over the results, returning each entity and its index.
for (i, entity) in enumerate(q):
(map_updates, map_deletes) = self.map(entity)
self.to_put.extend(map_updates)
self.to_delete.extend(map_deletes)
# Do updates and deletes in batches.
if (i + 1) % batch_size == 0:
self._batch_write()
# Record the last entity we processed.
start_key = entity.key()
self._batch_write()
except DeadlineExceededError:
# Write any unfinished updates to the datastore.
self._batch_write()
# Queue a new task to pick up where we left off.
deferred.defer(self._continue, start_key, batch_size)
return
self.finish()
class FileInfo(db.Model):
blob = blobstore.BlobReferenceProperty(required=True)
download_count = db.IntegerProperty(required=True, count=0)
uploaded_by = db.UserProperty(required=True)
uploaded_at = db.DateTimeProperty(required=True, auto_now_add=True)
class DailyTotal(db.Model):
date = db.DateProperty(required=True, auto_now_add=True)
file_count = db.IntegerProperty(required=True)
download_count = db.IntegerProperty(required=True)
class DownloadCountMapper(Mapper):
KIND = FileInfo
def __init__(self):
self.file_count = 0
self.download_count = 0
def map(self, file):
self.file_count += 1
self.download_count += file.download_count
def finish(self):
total = DailyTotal(file_count=self.file_count,
download_count=self.download_count)
total.put()
Can you tell me what I should do?
Thank you
This line is the culprit:
download_count = db.IntegerProperty(required=True, count=0)
The IntegerProperty constructor doesn't know what to do with count. Maybe you meant this:
download_count = db.IntegerProperty(required=True, default=0)

Categories