BennieC 0 Posted July 6, 2022 Hi, I have a Delphi application and am calling some Python functions from it. The function in Python returns a set of lists. How do I write Delphi code to receive these lists. Return statement in Python: return lboxes, lidxs, lconfidences In Delphi I have used single value returns but now need to receive three distinct lists.. Any suggestions or assistance Share this post Link to post
pyscripter 689 Posted July 6, 2022 The function return value is a tuple containing your lists. Share this post Link to post
BennieC 0 Posted July 9, 2022 Thank you. Of course my problem is that Delphi does not support tuples. How can I create variables in Delphi to return results into. Share this post Link to post
pyscripter 689 Posted July 9, 2022 You can use either VarPy or the low-level python API to manipulate python tuples (e.g PyTuple_GetItem, PyTuple_SetItem etc.) with VarPyth the unit tests give you a good idea of things you can do: c := VarPythonCreate([1, 2, 3, 4], stTuple); // test a tuple Assert.IsTrue( VarIsPythonTuple(c) ); Assert.IsTrue( VarIsPythonSequence(c) ); Assert.IsTrue( c.GetItem(1) = 2 ); Assert.IsTrue( c.Length = 4 ); c := NewPythonTuple(3); c.SetItem(0, 1); c.SetItem(1, 2); c.SetItem(2, 3); Assert.IsTrue( VarIsPythonTuple(c) ); Assert.IsTrue( VarIsPythonSequence(c) ); Assert.IsTrue( c.GetItem(1) = 2 ); Assert.IsTrue( c.Length = 3 ); from python4delphi/VarPythTest.pas at master · pyscripter/python4delphi (github.com) Share this post Link to post
BennieC 0 Posted July 11, 2022 Thanks a lot - I am progressing. I now have a next problem in getting a list Python Code import P4D_P5_Python as md from myPyMod import np_array myboxes = [] myboxes = md.CreateArray() THIS JUST CREATES AN ARRAY OF RECTANGLES [t, l, w, h] Delphi Code PythonEngine1.ExecStrings(mePyInit.Lines); // This creates and runs the Python code FIRST ATTEMPT // Sien Demo 17 myV := PythonModule1.GetVarAsVariant('myboxes'); THIS FAILS WITH ACCESS VIOLATION SECOND ATTEMPT // From P4D tutorial 2 for var V in VarPyIterate(MainModule.myboxes) do THIS WORKS BUT VALUES V ARE STRINGS begin // If arrays are rectangles assert( varispythonlist(V)); Vlength := length(V); Listbox1.Items.Add('len(V) = ' + inttostr(Vlength)); Listbox1.items.add(V); end; ANy suggestions on where I am going wrong Share this post Link to post
pyscripter 689 Posted July 11, 2022 (edited) for var V in VarPyIterate(MainModule.myboxes) do V will be a python variant pointing to whatever is inside myboxes. Listbox1.items.add(V); The above converts the python variant to string. Edited July 11, 2022 by pyscripter Share this post Link to post
BennieC 0 Posted July 12, 2022 Thank you I gathered that, but when I use my first attempt: GetVarAsVariant it fails with ACCESS VIOLATION I still struggle to see how Delphi can convert a python variant to the required format. Must I first declare the structure in Delphi? What if I don't know the structure? I have attached my test program in which I am trying to understand the principles - maybe you can understand my problem better in this. In the long run I will have to deal with quite complex tuples from my Yolo ML project (Which currently runs in C#) but I need to understand the principles first. Regards prjP4D_P5_VarPyth.zip Share this post Link to post
BennieC 0 Posted July 13, 2022 I have found the offending code in PythonEngine - function PyObjectAsVariant In line 5390 there is an ExtractDate(Result) line. Following thorugh it goes to the ExtractDate function with an unassigned value for date, but expecting to decode obj which is nil at this point - hence the error. This is nil because Getvar in GetVarAsVariant returned a nil for obj. Now clearly my Python object has a value as it returns it as strings in the VarPyIterate function. Can this help to explain my problem? Regards Share this post Link to post
pyscripter 689 Posted July 13, 2022 (edited) I am not sure what is the problem you are trying to solve. Your "Second attempt" should work. In your "First attempt" myV := PythonModule1.GetVarAsVariant('myboxes'); fails because PythonModule1 has no variable 'myboxes'. myboxes will be part of the main module namespace after your code gets executed. GetVarAsVariant can be improved to avoid the access violation. function TPythonModule.GetVarAsVariant( const varName : AnsiString ) : Variant; var obj : PPyObject; begin CheckEngine; with Engine do begin obj := GetVar( varName ); if Assigned(obj) then try Result := PyObjectAsVariant( obj ); finally Py_XDecRef(obj); end; end; end; Edited July 13, 2022 by pyscripter Share this post Link to post
BennieC 0 Posted July 19, 2022 I am still struggling with getting my results into Delphi. I have used direct access to the Python function as shown in the screencopy and in fact receive the correct results in Delphi using Code insight as shown. But I have no success in actually accessing this tuple from Delphi There are three items in the tuple, the first containing a list of arrays, the second an array and the third a list of values. How do I individually access these values - some sample code will help as I can't find anything in the demos and my knowledge of variants still seem to be inadequate. Kind regards Share this post Link to post