Kivy getting values from Popup Window and use it at a Screen - popup

Hi i am new to kivy and just started programming. So what i want to do is,once a user key in a valid date/time in the popup window, popup will close and will goes to a screen and create buttons. May i know how to pass the values get from getDay() which is dayoutput,timeoutput from popupwindow and transfer use it in another other class? and be able to use in the VariesTimeScreen?
Thank your for taking your time to help :)
class SetDateTime(Popup):
def getDay(self):
set_day = (self.ids.dayofmonth).text
set_month = (self.ids.month).text
set_year = (self.ids.year).text
set_hour = (self.ids.houroftime).text
set_minutes = (self.ids.minuteoftime).text
wrongtime = self.ids.wronginput_time
#Calculate Date and Time only when user input a valid number
if set_day.isdigit() and set_month.isdigit() and
set_year.isdigit()andset_hour.isdigit()
and set_minutes.isdigit():
try:
set_date = datetime.date(int(set_year),
int(set_month),int(set_day))
set_time = datetime.time(int(set_hour), int(set_minutes))
if not (set_date >= counttime.todaydate()):
wrongtime.text = "[color=#FF0000]Date is out of
range[/color]"
if not (set_time >= counttime.todaytime()):
wrongtime.text = "[color=#FF0000]Time is out of
range[/color]"
dayoutput = counttime.calculatedate(set_date)
timeoutput = set_hour + set_minutes
self.dismiss()
return dayoutput,timeoutput
except ValueError:
wrongtime.text = "[color=#FF0000]Please enter a valid
datetime.[/color]"
else:
wrongtime.text = "[color=#FF0000]Please enter a valid
date[/color]"
class VariesTimeScreen(Screen):
def __init__(self, **kwargs):
super(VariesTimeScreen, self).__init__(**kwargs)
a = '_icons_/mcdonald.png'
b = '_icons_/kfc.png'
c = '_icons_/subway.png'
Outlet_Store = [a,b,c]
layout = GridLayout(rows=1, spacing=100, size_hint_y=None,
pos_hint ={"top":.6,"x":0.2})
layout.bind(minimum_height=layout.setter('height'))
#Before the for loop there will be an if statement which is
the Day and Time i get from getDay() values. This part i'm
unsure how to retrieve the values from the SetDateTime Class
for image in Outlet_Store:
food_image = ImageButton(size_hint=(None, None),size=
(100,100),source=image)
layout.add_widget(food_image)
self.add_widget(layout)

One problem with your design is that the VariesTimeScreen is created very early in the App run, like when the GUI is created. So, the day and time from the SetDateTime Popup is not yet available. One way to handle this is to add an on_enter() method to the VariesTimeScreen to make any adjustments to the Screen at that time. To do that, I added Properties to the VariesTimeScreen:
class VariesTimeScreen(Screen):
day = StringProperty('None')
time = NumericProperty(0)
And add the on_enter() method to the VariesTimeScreen class:
def on_enter(self, *args):
print('day:', self.day, ', time:', self.time)
# make changes to the Screen
And then change the SetDateTime class slightly:
class SetDateTime(Popup):
def getDay(self):
set_day = (self.ids.dayofmonth).text
set_month = (self.ids.month).text
set_year = (self.ids.year).text
set_hour = (self.ids.houroftime).text
set_minutes = (self.ids.minuteoftime).text
wrongtime = self.ids.wronginput_time
# Calculate Date and Time only when user input a valid number
if set_day.isdigit() and set_month.isdigit() and set_year.isdigit() and set_hour.isdigit() and set_minutes.isdigit():
try:
set_date = datetime.date(int(set_year),
int(set_month), int(set_day))
set_time = datetime.time(int(set_hour), int(set_minutes))
if not (set_date >= counttime.todaydate()):
wrongtime.text = "[color=#FF0000]Date is out of range[ / color]"
if not (set_time >= counttime.todaytime()):
wrongtime.text = "[color=#FF0000]Time is out of range[ / color]"
dayoutput = counttime.calculatedate(set_date)
timeoutput = set_hour + set_minutes
# get the VariesTimeScreen
varies_time = App.get_running_app().root.ids.screen_manager.get_screen('variestime_screen')
# set the day and time for the VariesTimeScreen
varies_time.day = dayoutput
varies_time.time = timeoutput
# switch to the VariesTimeScreen
App.get_running_app().change_screen('variestime_screen')
# dismiss Popup
self.dismiss()
except ValueError:
wrongtime.text = "[color=#FF0000]Please enter a valid datetime.[ / color]"
else:
wrongtime.text = "[color=#FF0000]Please enter a valid date[ / color]"
The only changes are to set the day and time in the VariesTimeScreen, and to actually switch to the VariesTimeScreen. The switch to the VariesTimeScreen doesn't have to happen there, once the day and time are set, the on_enter() method will get called whenever it becomes the current Screen.

Related

How to use timer.performWithDelay with a method call

I'm using a Lua class to create two objects, each of which must check where the other is to determine their movement. I'm attempting to use timer.performWithDelay to have them check every second, but for some reason when I try to do this, the line
o.moveCheckTimer = timer.performWithDelay(1000, o:moveCheck, 0)
in the class constructor throws an error stating that "Function arguments are expected near ','".
I have attempted to use an anonymous function like this:
o.moveCheckTimer = timer.performWithDelay(1000, function() o:moveCheck() end, 0)
but that causes the timer of both objects to only call the function for the most recent object that was created and not for itself (also very confusing behavior, and if anyone knows why this happens I would love to learn why).
I have dug through the API and info on method calls thoroughly, but I can't seem to find anything that uses them both together, and I feel like I'm missing something.
How can I use the method call as the listener for this timer?
Here is the full constructor:
Melee = {}
Melee.__index = Melee
function Melee:new(id, name, lane, side)
local o = {}
setmetatable(o, Melee)
o.id = id
o.name = name
o.lane = lane
o.side = side
if name == "spearman" then
o.maxhp = 100
o.range = 1
o.damage = {10, 20}
o.imageName = "images/rebels/spearman.png"
else
error("Attempted to create melee unit with undefined name")
end
o.hp = o.maxhp
--Display self
o.image = display.newImageRect(mainGroup, "images/rebels/spearman.png", 80, 80)
o.image.x = 0
o.image.y = lanes[lane]
o.image.anchorY = 1
if side == 2 then
o.image.xScale = -1
o.image:setFillColor(0.8)
o.image.x = display.contentWidth - 100
end
--Move and attack
local destination = display.contentWidth
if side == 2 then
destination = 0
end
o.moving = 1
o.movement = transition.to(o.image, {x = destination, time = 30000+math.random(-200,200)})
o.moveCheckTimer = timer.performWithDelay(1000, o:moveCheck, 0)
--o.attackTimer = timer.performWithDelay(1000, self:attack, 0)
return o
end

Calling a custom function in Rasa Actions

I am facing a problem in developing a chatbot using rasa .
I am trying to call a custom function in rasa action file. But i am getting an error saying "name 'areThereAnyErrors' is not defined"
here is my action class. I want to call areThereAnyErrors function from run method. Could someone please help how to resolve this?
class ActionDayStatus(Action):
def areThereAnyErrors(procid):
errormessagecursor = connection.cursor()
errormessagecursor.execute(u"select count(*) from MT_PROSS_MEAGE where pro_id = :procid and msg_T = :messageT",{"procid": procid, "messageT": 'E'})
counts = errormessagecursor.fetchone()
errorCount = counts[0]
print("error count is {}".format(errorCount))
if errorCount == 0:
return False
else:
return True
def name(self):
return 'action_day_status'
def run(self, dispatcher, tracker, domain):
import cx_Oracle
import datetime
# Connect as user "hr" with password "welcome" to the "oraclepdb" service running on this computer.
conn_str = dbconnection
connection = cx_Oracle.connect(conn_str)
cursor = connection.cursor()
dateIndicator = tracker.get_slot('requiredDate')
delta = datetime.timedelta(days = 1)
now = datetime.datetime.now()
currentDate = (now - delta).strftime('%Y-%m-%d')
print(currentDate)
cursor = connection.cursor()
cursor.execute(u"select * from M_POCESS_FILE where CREATE_DATE >= TO_DATE(:createDate,'YYYY/MM/DD') fetch first 50 rows only",{"createDate":currentDate})
all_files = cursor.fetchall()
total_number_of_files = len(all_files)
print("total_number_of_files are {}".format(total_number_of_files))
Answer given by one of the intellectuals :
https://realpython.com/instance-class-and-static-methods-demystified/ Decide whether you want a static method or class method or instance method and call it appropriately . Also when you are using connection within the function it should be a member variable or passed to the method You dont have self as a parameter so you may be intending it as a static method - but you dont have it created as such

EPPlus chart(pie,barchart) selected(B2,B36,B38) .. etc excel cells

I have similar to the link below problem.
EPPlus chart from list of single excel cells. How?
I tried the code but it shows it twice in the chart. For example:
This code show excel chart -> select data-> horizontal(category) axis labels tab you show 100,100,300,600 write. What is the reason for this? The chart is written twice the first data I did not find a solution to the problem.
I think you just discovered a bug with EPPlus. Shame on me for not noticing that with that post you reference. It seems that when using the Excel union range selector (the cell names separated by commas) the iterator for the ExcelRange class returns a double reference to the first cell, in this case B2.
A work around would be to use the other overload for Series.Add which will take two string ranges. Here is a unit test that show the problem and the workaround:
[TestMethod]
public void Chart_From_Cell_Union_Selector_Bug_Test()
{
var existingFile = new FileInfo(#"c:\temp\Chart_From_Cell_Union_Selector_Bug_Test.xlsx");
if (existingFile.Exists)
existingFile.Delete();
using (var pck = new ExcelPackage(existingFile))
{
var myWorkSheet = pck.Workbook.Worksheets.Add("Content");
var ExcelWorksheet = pck.Workbook.Worksheets.Add("Chart");
//Some data
myWorkSheet.Cells["A1"].Value = "A";
myWorkSheet.Cells["A2"].Value = 100; myWorkSheet.Cells["A3"].Value = 400; myWorkSheet.Cells["A4"].Value = 200; myWorkSheet.Cells["A5"].Value = 300; myWorkSheet.Cells["A6"].Value = 600; myWorkSheet.Cells["A7"].Value = 500;
myWorkSheet.Cells["B1"].Value = "B";
myWorkSheet.Cells["B2"].Value = 300; myWorkSheet.Cells["B3"].Value = 200; myWorkSheet.Cells["B4"].Value = 1000; myWorkSheet.Cells["B5"].Value = 600; myWorkSheet.Cells["B6"].Value = 500; myWorkSheet.Cells["B7"].Value = 200;
//Pie chart shows with EXTRA B2 entry due to problem with ExcelRange Enumerator
ExcelRange values = myWorkSheet.Cells["B2,B4,B6"]; //when the iterator is evaluated it will return the first cell twice: "B2,B2,B4,B6"
ExcelRange xvalues = myWorkSheet.Cells["A2,A4,A6"]; //when the iterator is evaluated it will return the first cell twice: "A2,A2,A4,A6"
var chartBug = ExcelWorksheet.Drawings.AddChart("Chart BAD", eChartType.Pie);
chartBug.Series.Add(values, xvalues);
chartBug.Title.Text = "Using ExcelRange";
//Pie chart shows correctly when using string addresses and avoiding ExcelRange
var chartGood = ExcelWorksheet.Drawings.AddChart("Chart GOOD", eChartType.Pie);
chartGood.SetPosition(10, 0, 0, 0);
chartGood.Series.Add("Content!B2,Content!B4,Content!B6", "Content!A2,Content!A4,Content!A6");
chartGood.Title.Text = "Using String References";
pck.Save();
}
}
Here is the output:
I will post it as an issue on their codeplex page to see if they can get it fixed for the next release.

How can you populate a WTForms FieldList after the validate_on_submit() block?

There is a real lack of documentation on how to work with WTForms' FieldList. So thanks to the internet I've been able to hack together the following:
Form:
class BranchForm(Form):
name = StringField('Name', validators = [Required()])
equipment = FieldList(SelectField('Equipment', validators=[Required()], coerce=int,
choices = [(x.id, x.name) for x in Equipment.query.all()]))
mod = FieldList(StringField('Method of Delivery', validators = [Optional()]))
View:
def edit_branch(id):
branch = Branch.query.filter_by(id=id).first()
#populate data_in to be used by BranchForm
data_in = []
for eq_obj in branch.equipment_assoc:
data_in.append(('equipment', eq_obj.equipment.id))
data_in.append(('mod', eq_obj.mod))
editform = BranchForm(data=MultiDict(data_in))
if editform.validate_on_submit():
branch.name = editform.name.data
db.session.add(branch)
db.session.commit()
return redirect('/admin/branches/' + str(branch.id))
editform.name.data = branch.name
return render_template("branch_edit.html",
title="Edit Branch",
branch = branch,
editform = editform)
What's throwing me off is that everywhere else that I've used a WTForm Form and populated the fields with data from my db (like for edit forms), I've had to populate these form fields after the form.validate_on_submit() block, because if not, then the form will never update as whatever is submitted is immediately overwritten.
See "editform.name.data = branch.name" (this is how I've always done it)
From every example I've found online about populating a FieldList, it apparently must be done during instantiation, but the form has to be instantiated before the validate_on_submit() as well because validate_on_submit() is a method of the form object.
See "editform = BranchForm(data=MultiDict(data_in))" (this is how I've seen FieldLists populated in all the examples I've seen.)
How can I go about populating my form with its field lists?
Alright, so a buddy helped me figure this one out. Here's what I ended up with:
Form:
class BranchForm(Form):
name = StringField('Name', validators = [Required()])
equipment = FieldList(SelectField('Equipment', validators=[Required()], coerce=int,
choices = [(x.id, x.name) for x in Equipment.query.all()]))
mod = FieldList(StringField('Method of Delivery', validators = [Optional()]))
def populate_assoc(self, branch_obj):
i = 0
branch_obj.name = self.name.data
for assoc_obj in branch_obj.equipment_assoc:
assoc_obj.equipment_id = self.equipment[i].data
assoc_obj.mod = self.mod[i].data
i += 1
View:
def edit_branch(id):
branch = Branch.query.filter_by(id=id).first()
if request.method == 'POST':
editform = BranchForm()
if editform.validate_on_submit():
editform.populate_assoc(branch)
db.session.add(branch)
db.session.commit()
return redirect('/admin/branches/' + str(branch.id))
#populate data_in to be used
data_in = []
for eq_obj in branch.equipment_assoc:
data_in.append(('equipment', eq_obj.equipment.id))
data_in.append(('mod', eq_obj.mod))
editform = BranchForm(data=MultiDict(data_in))
editform.name.data = branch.name
return render_template("branch_edit.html",
title="Edit Branch",
branch = branch,
editform = editform)
The trick was really to step away from using form.validate_on_submit() as my logic separator, since it relies on the form object. His idea was to use the if request.method == 'POST': for this purpose. This way I can instantiate my form in two different ways. One gets populated for display, the other is only instantiated if the request method is POST, thus retaining the information submitted in the form.
To finish the job I added the populate_assoc method to my form class so that I can easily place the information from the form into my association model.
WtForms has a populate_obj() method. Maybe that's what you're after?
def edit_branch(id):
branch = Branch.query.filter_by(id=id).first()
editform = BranchForm(obj=branch)
if editform.validate_on_submit():
editform.populate_obj(branch)
db.session.commit()
return redirect('/admin/branches/' + str(branch.id))
return render_template("branch_edit.html",
title="Edit Branch",
branch = branch,
editform = editform)

Libreoffice Calc run macro with HYPERLINK

I'm trying to use hyperlinks instead of buttons to run Basic macros. It seems to be more natural to me because hyperlinks are directly connected to a cell and buttons are not.
I'm using the following Formula:
=HYPERLINK("vnd.sun.star.script:Standard.Module1.Test?language=Basic&location=document";"Check")
It should call the Subroutine Test placed in the document's macros under Standard.Module1 and display the Text 'Check' in the Cell it is written.
This works absolutely fine with libreoffice 3.6.1.2 but it doesn't work at all with version 4.1.4.2. I can't see any errors it just happens nothing at all. I tried to simply click the Hyperlink and also to hold CTRL and click it. Same result - nothing.
When I use a button the macro works as expected.
Does anyone know how to solve this problem?
This seems to be a bug in Calc. The protocol vnd.sun.star.script runs in hyperlink URLs in Writer still in version 4.2. But in Calc it runs not.
As a workaround you could have the following function attached to the sheet event "Double click". Then the macro runs if you double click the cell with the =HYPERLINK formula.
The last two versions are the results of my first ideas. I will let them in the answer because of comprehensibility reasons. But this last version is the best workaround in my opinion. It will closest work like the original vnd.sun.star.script: URL.
public function Doubelclicked(target) as Boolean
if left(target.formula, 32) = "=HYPERLINK(""vnd.sun.star.script:" then
sFormulaHyperlink = target.formula
sMacroURLRaw = mid(sFormulaHyperlink, 13, instr(13, sFormulaHyperlink, ";") - 13)
target.formula = "=""" & sMacroURLRaw
sMacroURL = target.string
target.formula = sFormulaHyperlink
oDisp = createUnoService("com.sun.star.frame.DispatchHelper")
dim args(0) as new com.sun.star.beans.PropertyValue
args(0).Name = "URL"
args(0).Value = sMacroURL
oFrame = ThisComponent.CurrentController.Frame
oDisp.executeDispatch(oFrame, sMacroURL, "", 0, args)
end if
Doubelclicked = false
end function
Here are the previous versions:
public function Doubelclicked(target) as Boolean
if left(target.formula, 32) = "=HYPERLINK(""vnd.sun.star.script:" then
sMacroURL = mid(target.formula, 13, instr(13, target.formula, chr(34))-13)
oDisp = createUnoService("com.sun.star.frame.DispatchHelper")
oFrame = ThisComponent.CurrentController.Frame
oDisp.executeDispatch(oFrame, sMacroURL, "", 0, Array())
end if
Doubelclicked = false
end function
With this it is not possible to pass parameters in the macro URL. But if it only is the goal to get the address of the cell from which the macro was called, then this is possible because we have the target of the double click. So i have updated my workaround.
public function Doubelclicked(target) as Boolean
if left(target.formula, 32) = "=HYPERLINK(""vnd.sun.star.script:" then
lStartLocation = instr(13, target.formula,"&location=")
if lStartLocation > 0 then
lEndLocation = instr(lStartLocation + 1, target.formula,"&")
if lEndLocation = 0 then lEndLocation = instr(lStartLocation + 1, target.formula,"""")
sMacroURL = mid(target.formula, 13, lEndLocation - 13)
'msgbox sMacroURL
oDisp = createUnoService("com.sun.star.frame.DispatchHelper")
dim args(2) as new com.sun.star.beans.PropertyValue
args(0).Name = "TargetAddress"
args(0).Value = target.AbsoluteName
oFrame = ThisComponent.CurrentController.Frame
oDisp.executeDispatch(oFrame, sMacroURL, "", 0, args)
end if
end if
Doubelclicked = false
end function
Greetings
Axel