virtual wx.ListCtrl raises wxAssertionError on SetItemCount - python

I want to create a custom ListCtrl "MyListCtrlCrafting" which pulls the data from a different class called "DBInterface" (actually it is not a real database, but a sophisticated python dictionary). There are tutorials on how to do that, I followed "Python in Action". The main points are: inherit from ListCtrl an set the style parameter to wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.LC_VIRTUAL, call SetItemCount() during init() and override some methods.
To test how that works I made a small App which consists only of one (main-)frame, the virtual ListCtrl and a rudimentary version of DBInterface. Everything works out fine in this setting. But when I connect the classes of the real App, I get a Traceback:
Traceback (most recent call last):
File "DesktopCrafter.py", line 198, in <module>
controller = AppCtrl()
File "DesktopCrafter.py", line 186, in __init__
self.frame = GUI.MainWindow(back_end=self.back_end, crafting_controller=self.crafting_controller, parent=None, title='Desktop Crafter')
...
self.view = MyListCtrlCrafting(name='crafting-hand', back_end=self.db, crafting_controller=self.cc, parent=self, id=wx.ID_ANY)
File "d:\workspace-fun\DesktopCrafter\dc\util\DCUI.py", line 107, in __init__
self.bindData()
File "d:\workspace-fun\DesktopCrafter\dc\util\DCUI.py", line 121, in bindData
self.SetItemCount(count)
wx._core.wxAssertionError: C++ assertion "m_count == ListView_GetItemCount(GetHwnd())" failed at ..\..\src\msw\listctrl.cpp(3120) in wxListCtrl::SetItemCount(): m_count should match ListView_GetItemCount
In contrast to the simple App, the virtualListCtrl is now deeply nested. Can this error just be produced by wrong connections inside this nesting or between DBInterface and the ListCtrl? Or do I have to understand how m_count is calculated, to solve this error? If so, how can I read the _core file? I already read about ListCtrl in the core.py file, but it doesn't contain the relevant parts.
My problem with this traceback is that I don't understand why it is raised during SetItemCount(). This method should be something like a definition and since it is dealing with rows of a list, it should accept positive integers, and maybe 0, and maybe also -1 for standard. I plug in 5, so this cannot be the real problem going on here(?)
Any help or hint is much appreciated!
The complete Traceback:
Traceback (most recent call last):
File "DesktopCrafter.py", line 198, in <module>
controller = AppCtrl()
File "DesktopCrafter.py", line 186, in __init__
self.frame = GUI.MainWindow(back_end=self.back_end, crafting_controller=self.crafting_controller, parent=None, title='Desktop Crafter')
File "d:\workspace-fun\DesktopCrafter\dc\util\DCUI.py", line 285, in __init__
self.InitUI()
File "d:\workspace-fun\DesktopCrafter\dc\util\DCUI.py", line 299, in InitUI
self.panel = MainPanel(back_end=self.db, crafting_controller=self.cc)
File "d:\workspace-fun\DesktopCrafter\dc\util\DCUI.py", line 251, in __init__
self.splitter = MySplitter(back_end=back_end, crafting_controller=crafting_controller)
File "d:\workspace-fun\DesktopCrafter\dc\util\DCUI.py", line 229, in __init__
self.l_frame = LPanel(back_end=back_end, crafting_controller=crafting_controller)
File "d:\workspace-fun\DesktopCrafter\dc\util\DCUI.py", line 188, in __init__
self.panel = CraftingPanel(back_end=back_end, crafting_controller=crafting_controller, *args, **kwargs)
File "d:\workspace-fun\DesktopCrafter\dc\util\DCUI.py", line 154, in __init__
self.view = MyListCtrlCrafting(name='crafting-hand', back_end=self.db, crafting_controller=self.cc, parent=self, id=wx.ID_ANY)
File "d:\workspace-fun\DesktopCrafter\dc\util\DCUI.py", line 107, in __init__
self.bindData()
File "d:\workspace-fun\DesktopCrafter\dc\util\DCUI.py", line 121, in bindData
self.SetItemCount(count)
wx._core.wxAssertionError: C++ assertion "m_count == ListView_GetItemCount(GetHwnd())" failed at ..\..\src\msw\listctrl.cpp(3120) in wxListCtrl::SetItemCount(): m_count should match ListView_GetItemCount
The virtual ListCtrl (both print's give me the expected results):
class MyListCtrlCrafting(wx.ListCtrl):
def __init__(self, name, back_end, crafting_controller, *args, **kwargs):
wx.ListCtrl.__init__(self, style=wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.LC_VIRTUAL, *args, **kwargs)
self.name = name
self.db = back_end
self.cc = crafting_controller
#print(self.db.retrieveValue(['player', self.name]))
self.Bind(wx.EVT_LIST_CACHE_HINT, self.DoCacheItems)
self.bindData()
self.InsertColumn(0, "Slot")
self.InsertColumn(1, "Item")
self.InsertColumn(2, "Amount")
print("initialized MyListCtrl")
def bindData(self):
data = self.db.retrieveValue(['player', self.name])
count = len(data)
#print(count)
self.itemDataMap = {i: ('slot'+str(i+1), data[str(i)]['item'], data[str(i)]['amount']) for i in range(count)}
self.SetItemCount(count)
def DoCacheItems(self, e):
self.db.updateCache(e.GetCacheFrom(), e.GetCacheTo())
def OnGetItemText(self, row_no, col_no):
data = self.db.retrieveValue(['player', self.name, str(row_no)])
return data[col_no]
def OnGetItemAttr(self, item): return None
def OnGetItemImage(self, item): return -1
def OnBackEndUpdated(self):
self.bindData()
self.RefreshItems(0, self.GetItemCount())
The DBInterface:
class DBInterface(dict):
def __init__(self, path, *args, **kwargs):
super(DBInterface, self).__init__(*args, **kwargs)
self.path = path
def load(self):
with open(self.path, 'r') as f:
try:
self.update(json.loads(f.read()))
except Exception as e:
print(e); print(self.path)
def save(self):
self.path.ensure()
with open(self.path, 'w') as f:
f.write(json.dumps(self))
def retrieveValue(self, path):
a = self
for i in range(len(path)):
a = a[path[i]]
return a

That assert is basically a check to ensure that the operation (setting the count) was successful, by asking the native control how many items it has (which should have been set by the prior API call. It seems like something that really shouldn't be able to fail, although obviously it is. Perhaps something is resetting or changing the native control somehow? Are there any threads involved?
I don't have a solid answer for you, but as advice I would suggest taking the small sample that works and build it up step by step until it matches the window hierarchy and environment and basic features of that part of the full application where it is broken. Eventually it should start failing the same way and then you'll know what changed that triggered it and can look more closely at that.

Related

Kivy Button: on_press function called before its being pressed

Im writing a Sudoku solver UI in Kivy.
I wanted to add a button, which upon being pressed, solves the Grid. The function works, although when I assign it to a button as the on_press function, it somehow runs before the button is pressed. I've tried everything. I get an Assertion Error. When I just use the solve function, it works. Not with the button, though.
Thank you for helping.
This is the __init__ function:
class SudokuGrid(GridLayout):
def __init__(self, **kwargs):
super(SudokuGrid, self).__init__(**kwargs)
self.grid = [[8,7,0, 0,0,0, 0,0,0],
[0,0,0, 9,0,0, 0,0,4],
[0,2,0, 7,0,0, 1,0,5],
[0,0,9, 6,0,0, 0,3,0],
[0,0,0, 0,0,0, 0,0,9],
[0,0,6, 5,4,0, 0,0,0],
[6,9,0, 0,0,0, 7,0,0],
[2,0,0, 0,0,7, 4,0,0],
[0,0,0, 3,0,0, 0,1,0]]
self.add_widget(Button(on_press=self.solve()))
self.cols = 3
self.rows = 4
self.load_grid()
And this my solve function:
def solve(self):
for x in range(9):
for y in range(9):
if self.grid[y][x] == 0:
for n in range(1,10):
if self.possible(y,x,n):
self.grid[y][x] = n
self.solve()
self.grid[y][x] = 0
return
self.load_grid()
print(np.matrix(self.grid))
I know that the function is run, because before the App terminates, I get the output of the solved Grid.
This is the Traceback:
Traceback (most recent call last):
File "C:\Users\victo\Desktop\portfolio\Sudoku\sudoku_app.py", line 217, in <module>
sudoku_game.run()
File "C:\Users\victo\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\app.py", line 829, in run
root = self.build()
File "C:\Users\victo\Desktop\portfolio\Sudoku\sudoku_app.py", line 205, in build
self.sudoku_grid = SudokuGrid()
File "C:\Users\victo\Desktop\portfolio\Sudoku\sudoku_app.py", line 73, in __init__
self.add_widget(Button(on_press=self.solve()))
File "C:\Users\victo\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\uix\behaviors\button.py", line 121, in __init__
super(ButtonBehavior, self).__init__(**kwargs)
File "C:\Users\victo\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\uix\label.py", line 318, in __init__
super(Label, self).__init__(**kwargs)
File "C:\Users\victo\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\uix\widget.py", line 369, in __init__
self.bind(**on_args)
File "kivy\_event.pyx", line 419, in kivy._event.EventDispatcher.bind
AssertionError: None is not callable
Okay so i figured it out. Erik said in his comment:
Try on_press=self.solve in stead of on_press=self.solve()
which worked, although I got another Error. I had one too many positional arguments for solve(). I fixed it by defining my method as:
def solve(self, *args)
Everything works now.

Creating a Glue job with AWS CDK (python) fails

I'm using Python wrappers for CDK to create a Glue job. The command attribute requires an object of type IResolvable | Job­Command­Property. I tried to put a JobCommandProperty object here but I'm getting an exception.
I created a JobCommandProperty object. I was looking for a .builder()function somewhere (similar than in the Java API), but couldn't find one.
from aws_cdk import (
aws_glue as glue,
aws_iam as iam,
core
)
class ScheduledGlueJob (core.Stack):
def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
super().__init__(scope, id, **kwargs)
policy_statement = iam.PolicyStatement(
actions=['logs:*','s3:*','ec2:*','iam:*','cloudwatch:*','dynamodb:*','glue:*']
)
policy_statement.add_all_resources()
glue_job_role = iam.Role(
self,
'Glue-Job-Role',
assumed_by=iam.ServicePrincipal('glue.amazonaws.com')
).add_to_policy(
policy_statement
)
job = glue.CfnJob(
self,
'glue-test-job',
role=glue_job_role,
allocated_capacity=10,
command=glue.CfnJob.JobCommandProperty(
name='glueetl',
script_location='s3://my-bucket/glue-scripts/job.scala'
))
The error message is this:
$cdk synth
Traceback (most recent call last):
File "app.py", line 30, in <module>
glue_job = ScheduledGlueJob(app, 'Cronned-Glue-Job')
File "/Users/d439087/IdeaProjects/ds/test_cdk/.env/lib/python3.7/site-packages/jsii/_runtime.py", line 66, in __call__
inst = super().__call__(*args, **kwargs)
File "/Users/d439087/IdeaProjects/ds/test_cdk/glue/scheduled_job.py", line 33, in __init__
script_location='s3://my-bucket/glue-scripts/job.scala'
File "/Users/d439087/IdeaProjects/ds/test_cdk/.env/lib/python3.7/site-packages/jsii/_runtime.py", line 66, in __call__
inst = super().__call__(*args, **kwargs)
File "/Users/d439087/IdeaProjects/ds/test_cdk/.env/lib/python3.7/site-packages/aws_cdk/aws_glue/__init__.py", line 2040, in __init__
jsii.create(CfnJob, self, [scope, id, props])
File "/Users/d439087/IdeaProjects/ds/test_cdk/.env/lib/python3.7/site-packages/jsii/_kernel/__init__.py", line 208, in create
overrides=overrides,
File "/Users/d439087/IdeaProjects/ds/test_cdk/.env/lib/python3.7/site-packages/jsii/_kernel/providers/process.py", line 331, in create
return self._process.send(request, CreateResponse)
File "/Users/d439087/IdeaProjects/ds/test_cdk/.env/lib/python3.7/site-packages/jsii/_kernel/providers/process.py", line 316, in send
raise JSIIError(resp.error) from JavaScriptError(resp.stack)
jsii.errors.JSIIError: Expected 'string', got true (boolean)
Maybe someone has a working CDK (python) example to create a CfnJobobject?
Nevermind, the role attribute has to be of type string, I got confused by the JSII error message.
glue_job_role variable's type is no longer Role because you have added .add_to_policy to it. below code should work.
glue_job_role = iam.Role(
self,
'Glue-Job-Role',
assumed_by=iam.ServicePrincipal('glue.amazonaws.com')
)
glue_job_role.add_to_policy(
policy_statement
)
job = glue.CfnJob(
self,
'glue-test-job',
role=glue_job_role.arn,
allocated_capacity=10,
command=glue.CfnJob.JobCommandProperty(
name='glueetl',
script_location='s3://my-bucket/glue-scripts/job.scala'
))
Be aware that a crawler is not the same as a job, nonetheless I think the permissions are similar.
As of 16 August 2020, this is working for a crawler (and none of the previous answers unfortunately)
from aws_cdk import (
aws_iam as iam,
aws_glue as glue,
core
)
class MyDataScienceStack(core.Stack):
def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
super().__init__(scope, id, **kwargs)
statement = iam.PolicyStatement(actions=["s3:GetObject","s3:PutObject"],
resources=["arn:aws:s3:::mybucketname",
"arn:aws:s3:::mybucketname/data_warehouse/units/*"])
write_to_s3_policy = iam.PolicyDocument(statements=[statement])
glue_role = iam.Role(
self, 'GlueCrawlerFormyDataScienceRole',
role_name = 'GlueCrawlerFormyDataScienceRole',
inline_policies=[write_to_s3_policy],
assumed_by=iam.ServicePrincipal('glue.amazonaws.com'),
managed_policies=[iam.ManagedPolicy.from_aws_managed_policy_name('service-role/AWSGlueServiceRole')]
)
glue_crawler = glue.CfnCrawler(
self, 'glue-crawler-id',
description="Glue Crawler for my-data-science-s3",
name='any name',
database_name='units',
schedule={"scheduleExpression": "cron(5 * * * ? *)"},
role=glue_role.role_arn,
targets={"s3Targets": [{"path": "s3://mybucketname/data_warehouse/units"}]}
)

Error while porting Python 2 script to Python 3

I'm trying to port a project from Python 2 to 3 but am getting stuck with some errors. The code runs without a problem under Python 2.7.8. The error is the following:
[INFO ] [Text ] Provider: sdl2
Traceback (most recent call last):
File "C:\Users\xx\PycharmProjects\Simulator\simulator.pyw", line 2, in <module>
from bin.ui.ui import start
File "C:\Users\xx\PycharmProjects\Simulator\bin\ui\ui.py", line 30, in <module>
import bin.global_variables as global_variables
File "C:\Users\xx\PycharmProjects\Simulator\bin\global_variables.py", line 19, in <module>
ANTIBIOTICS = {"Generic Antibiotic": Antibiotic("Generic Antibiotic")}
File "C:\Users\DrPai\PycharmProjects\Simulator\bin\classes\Antibiotic.py", line 17, in __init__
line_width=1.01) # SmoothLinePlot
File "C:\Users\xx\PycharmProjects\Simulator\bin\deps\kivy_graph\__init__.py", line 1031, in __init__
super(Plot, self).__init__(**kwargs)
File "kivy\_event.pyx", line 243, in kivy._event.EventDispatcher.__init__
TypeError: object.__init__() takes exactly one argument (the instance to initialize)
The relevant part of the code that the error is pointing too are:
global_variables.py
ANTIBIOTICS = {"Generic Antibiotic": Antibiotic("Generic Antibiotic")}
Antibiotic.py
class Antibiotic(object):
_total_antibiotics = 0 # int
def __init__(self, name):
self._id = 'ant' + str(Antibiotic._total_antibiotics) # str
self._name = name # str
self._line_color = hsv_to_rgb(*NewColor.new_color()) # (R,G,B)
self._plot = SmoothLinePlot(points=[(0, 0)],
color=self._line_color,
line_width=1.01) # SmoothLinePlot
Antibiotic._total_antibiotics += 1
To draw the plots I'm relying on Kivy Graph widget accessible from here (https://github.com/kivy-garden/graph) and the error seems to be related to the code there:
__ init __.py
class Plot(EventDispatcher):
def __init__(self, **kwargs):
super(Plot, self).__init__(**kwargs)
self.ask_draw = Clock.create_trigger(self.draw)
self.bind(params=self.ask_draw, points=self.ask_draw)
self._drawings = self.create_drawings()
Kivy graph doesn't support line_width and removal of it solves the problem.

NotImplementedError() what does this mean, event profiler pyalgotrade

I'm trying to run pyalgotrade's event profiler. I'm using custom data, it works when I run it with the default stratergy/predicate 'BuyOnGap' however when I try and run it with a simple custom strategy it throw the error:
Traceback (most recent call last):
File "C:\Users\David\Desktop\Python\Coursera\Computational Finance\Week2\PyAlgoTrade\Bitfinex\FCT\FCT_single_event_test.py", line 43, in <module>
main(True)
File "C:\Users\David\Desktop\Python\Coursera\Computational Finance\Week2\PyAlgoTrade\Bitfinex\FCT\FCT_single_event_test.py", line 35, in main
eventProfiler.run(feed, True)
File "C:\Python27\lib\site-packages\pyalgotrade\eventprofiler.py", line 215, in run
disp.run()
File "C:\Python27\lib\site-packages\pyalgotrade\dispatcher.py", line 102, in run
eof, eventsDispatched = self.__dispatch()
File "C:\Python27\lib\site-packages\pyalgotrade\dispatcher.py", line 90, in __dispatch
if self.__dispatchSubject(subject, smallestDateTime):
File "C:\Python27\lib\site-packages\pyalgotrade\dispatcher.py", line 68, in __dispatchSubject
ret = subject.dispatch() is True
File "C:\Python27\lib\site-packages\pyalgotrade\feed\__init__.py", line 105, in dispatch
self.__event.emit(dateTime, values)
File "C:\Python27\lib\site-packages\pyalgotrade\observer.py", line 59, in emit
handler(*args, **kwargs)
File "C:\Python27\lib\site-packages\pyalgotrade\eventprofiler.py", line 172, in __onBars
eventOccurred = self.__predicate.eventOccurred(instrument, self.__feed[instrument])
File "C:\Python27\lib\site-packages\pyalgotrade\eventprofiler.py", line 89, in eventOccurred
raise NotImplementedError()
NotImplementedError
My code is:
from pyalgotrade import eventprofiler
from pyalgotrade.technical import stats
from pyalgotrade.technical import roc
from pyalgotrade.technical import ma
from pyalgotrade.barfeed import csvfeed
class single_event_strat( eventprofiler.Predicate ):
def __init__(self,feed):
self.__returns = {} # CLASS ATTR
for inst in feed.getRegisteredInstruments():
priceDS = feed[inst].getAdjCloseDataSeries() # STORE: priceDS ( a temporary representation )
self.__returns[inst] = roc.RateOfChange( priceDS, 1 )
# CALC: ATTR <- Returns over the adjusted close values, consumed priceDS
#( could be expressed as self.__returns[inst] = roc.RateOfChange( ( feed[inst].getAdjCloseDataSeries() ), 1 ),
#but would be less readable
def eventOccoured( self, instrument, aBarDS):
if (aBarDS[-1].getVolume() > 10 and aBarDS[-1].getClose() > 5 ):
return True
else:
return False
def main(plot):
feed = csvfeed.GenericBarFeed(0)
feed.addBarsFromCSV('FCT', "FCT_daily_converted.csv")
predicate = single_event_strat(feed)
eventProfiler = eventprofiler.Profiler( predicate, 5, 5)
eventProfiler.run(feed, True)
results = eventProfiler.getResults()
print "%d events found" % (results.getEventCount())
if plot:
eventprofiler.plot(results)
if __name__ == "__main__":
main(True)
What does this error mean ?
Does anyone know what's wrong and how to fix it ?
Here is a link to the eventprofiler code:
http://pastebin.com/QD220VQb
As a bonus does anyone know where I can find examples of the profiler being used? other that the example pyalgotrade gives, seen here
I think you just made a spelling mistake in eventOccurred method definition
def eventOccoured( self, instrument, aBarDS):
should be replaced by
def eventOccurred( self, instrument, aBarDS):

SpringPython error following the book: AttributeError: 'module' object has no attribute 'ObjBase'

Well, I bought the book Spring Python 1.1 and I have been facing some problems that I cannot solve. I am going to write the code of each file in order to make sure everything is clear. If some of you know what is the problem, please let me know because I am desperate.
simple_service.py
class Service(object):
def happy_birthday(self, name):
results = []
for i in range(4):
if i <= 2:
results.append("Happy birthday dear %s!" % name)
else:
results.append("Happy birthday to you!")
return results
simple_service_server_ctx.py
from springpython.config import *
from springpython.remoting.pyro import *
from simple_service import *
class HappyBirthdayContext(PythonConfig):
def __init__(self):
PythonConfig.__init__(self)
#Object
def target_service(self):
return Service()
#Object
def service_exporter(self):
exporter = PyroServiceExporter()
exporter.service = self.target_service()
exporter.service_name = "service"
exporter.service_host = "127.0.0.1"
exporter.service_port = "7766"
exporter.after_properties_set()
return exporter
simple_server.py
from springpython.context import *
from simple_service_server_ctx import *
if __name__ == "__main__":
ctx = ApplicationContext(HappyBirthdayContext())
ctx.get_object("service_exporter")
I run on a terminal: python simple_server
and then I got the following error:
(spring)kiko#kiko-laptop:~/examples/spring$ python simple_server.py
Traceback (most recent call last):
File "simple_server.py", line 6, in <module>
ctx = ApplicationContext(HappyBirthdayContext())
File "/home/kiko/.virtualenvs/spring/lib/python2.6/site-packages/springpython/context/__init__.py", line 45, in __init__
self.get_object(object_def.id, ignore_abstract=True)
File "/home/kiko/.virtualenvs/spring/lib/python2.6/site-packages/springpython/container/__init__.py", line 80, in get_object
comp = self._create_object(object_def)
File "/home/kiko/.virtualenvs/spring/lib/python2.6/site-packages/springpython/container/__init__.py", line 129, in _create_object
self._get_constructors_kw(object_def.named_constr))
File "/home/kiko/.virtualenvs/spring/lib/python2.6/site-packages/springpython/factory/__init__.py", line 62, in create_object
return self.method()
File "<string>", line 2, in service_exporter
File "/home/kiko/.virtualenvs/spring/lib/python2.6/site-packages/springpython/config/__init__.py", line 1370, in object_wrapper
return _object_wrapper(f, theScope, parent, log_func_name, *args, **kwargs)
File "/home/kiko/.virtualenvs/spring/lib/python2.6/site-packages/springpython/config/__init__.py", line 1350, in _object_wrapper
return _deco(f, scope, parent, log_func_name, *args, **kwargs)
File "/home/kiko/.virtualenvs/spring/lib/python2.6/site-packages/springpython/config/__init__.py", line 1345, in _deco
results = f(*args, **kwargs)
File "/home/kiko/examples/spring/simple_service_server_ctx.py", line 22, in service_exporter
exporter.after_properties_set()
File "/home/kiko/.virtualenvs/spring/lib/python2.6/site-packages/springpython/remoting/pyro/__init__.py", line 58, in after_properties_set
pyro_obj = Pyro.core.ObjBase()
AttributeError: 'module' object has no attribute 'ObjBase'
I have added on my own the line (file:simple_service_server_ctx.py):
exporter.after_properties_set()
since I read that it must be declared (line 19, link to source code).
Thanks in advance.
I wonder what your Pyro version is. Here using Pyro 3.9.1-1 from Ubuntu 10.04 I have no problems with running your code. Could it be that you're using Pyro 4.x which if I recall correctly was released after the book had been published?

Categories