How to use a Python class file in another script (in Matlab) - python

I am new to python and mainly use Matlab. I found some Python code on Github (https://github.com/simonmb/fragmentation_algorithm) that I want to run in Matlab, but I can't even manage to write a function in Python to run the code with any input. When I try to run the function I wrote (called 'RunFrag.py') in the Console in PyCharm, I only get the following error: NameError: name 'RunFrag' is not defined, even though the script is in the same folder. The file from Github ('fragmenter.py') defines a class and has the line __name__ == '__main__' and I have no idea how to deal with this, in Matlab classes occur rather rarely.
Can anyone help me with creating a function where I can just enter a SMILES molecule as input and get the fragmentation out?
Thanks in advance.
Here is the Code from the RunFrag function I wrote (the additionally needed fragmenter.py file can be found at the github link):
def RunFrag(smiles):
from .fragmenter import fragmenter
fragmentation_scheme = {
'CH2' : '[CH2]',
'OH' : '[OH]',
'CH3' : '[CH3]',
'CH2-CH2' : '[CH2][CH2]'
}
fragmentation_scheme_order1 = ['CH2-CH2', 'CH3', 'CH2', 'OH']
frg = fragmenter(fragmentation_scheme, fragmentation_scheme_order=fragmentation_scheme_order1, algorithm='simple')
fragmentation, success, fragmentation_matches = frg.fragment(smiles)
return smiles, fragmentation, success

Related

Issues with accessing PyObjects after writing

I am trying to do some fairly simple list manipulation, using a Jupyter notebook that calls a DLL function. I'd like my Jupyter notebook/Python code to pass in a Python list to a C++ function, which modifies the list, and then I'd like the Python code to be able to access the new list values.
I can actually read (in Jupyter) the items that were not edited by the C++ code, so there must be some issue with how I'm writing, but every example I can find looks just like my code. When I try to access the item in the list that the C++ code writes, my Jupyter kernel dies with no explanation; I've tried to run the same Python code in the terminal, and the terminal session just exits, again with no explanation.
Running on Windows 10, environment with Python 3.9.2. Here's the Python:
import os
import ctypes
import _ctypes
# Import the DLL
mydll = ctypes.cdll.LoadLibrary(*path to DLL*)
# Set up
data_in = [3,6,9]
mydll.testChange.argtypes = [ctypes.py_object]
mydll.testChange.restype = ctypes.c_float
mydll.testChange(data_in)
# Returns 0.08
After running this and closing the DLL, running data_in[1] returns 6, data_in[2] returns 9, and data_in[0] causes my kernel to die.
C code for the DLL:
float testChange(PyObject *data_out) {
Py_SetPythonHome(L"%user directory%\\anaconda3");
Py_Initialize();
PyList_SetItem(data_out, 0, PyLong_FromLong(1L));
return 0.08;
}
I can also insert a number of print statements in this code that show that I can read out all three items in the DLL both before and after the call to PyList_SetItem using calls like PyLong_AsLong(PyList_GetItem(data_out, 1)). It's not clear to me that any reference counts need changing or anything like that, but perhaps I misunderstand the idea. Any ideas you all have would be greatly appreciated.

How to execute python function as whole in VSCode (it splits and sends just the first line to an interpreter)

I'm getting used to VSCode in my daily Data Science remote workflow due to LiveShare feature.
So, upon executing functions it just executes the first line of code; if I mark the whole region then it does work, but it's cumbersome way of dealing with the issue.
I tried number of extensions, but none of them seem to solve the problem.
def gini_normalized(test, pred):
"""Simple normalized Gini based on Scikit-Learn's roc_auc_score"""
gini = lambda a, p: 2 * roc_auc_score(a, p) - 1
return gini(test, pred)
Executing the beginning of the function results in error:
def gini_normalized(test, pred):...
File "", line 1
def gini_normalized(test, pred):
^
SyntaxError: unexpected EOF while parsing
There's a solution for PyCharm: Python Smart Execute - https://plugins.jetbrains.com/plugin/11945-python-smart-execute. Also Atom's Hydrogen doesn't have such issue either.
Any ideas regarding VSCode?
Thanks!
I'm a developer on the VSCode DataScience features. Just to make sure that I'm understanding correctly. You would like the shift-enter command to send the entire function to the Interactive Window if you run it on the definition of the function?
If so, then yes, we don't currently support that. Shift-enter can run line by line or run a section of code that you manually highlight. If you want, you can use #%% lines in your code to put functions into code cells. Then when you are in a cell shift-enter will run that entire cell, might be the best current approach for you.
That smart execute does look interesting, if you would like to file that as a suggestion you can use our GitHub here to get it on our backlog to look at.
https://github.com/Microsoft/vscode-python
Hi you could click the symbol before each line and turn it into > (the indented codes of the function was hidden now). Then if you select the whole line and the next line, shift+enter could run them together.
enter image description here

Gurobi Python Error (NoneType has no len())

I need to write an optimization file for Gurobi (Python) that is a modified version of a classic TSP. I tried to run the example file from their website:
examples.gurobi.com/traveling-salesman-problem/
I always get the following error:
TypeError: object of type 'NoneType' has no len()
What do I need to change?
Thx
Full code: https://www.dropbox.com/s/ewisx805b3o2wq5/beispiel_opt.py?dl=0
I can confirm the error with the example code from Gurobi's website. At the first look the problem seems to be inside the subtour function, that returns None if sum(lengths) == n and the missing check for if tour is None inside the subtourlim function.
Instead of providing a fix for the specific code, I first checked the examples that Gurobi installs inside the specific installation directory:
Mac: /Library/gurobi810/mac64/examples/python/
Linux: /opt/gurobi800/linux64/examples/python/
Windows: c:\gurobi800\win64\examples\python\
And surprisingly the tsp.py from there runs without any errors. Note also that the two mentioned functions are revised. So I guess the example from the website is just a old version of the code.

Calling C++ code via embedded Python

I have successfully created a Python module that appears to work in isolation, but doesn't affect the program that is running it.
I have the following module:
BOOST_PYTHON_MODULE(mandala)
{
class_<state_mgr_t, state_mgr_t*, noncopyable>("states", no_init)
.def("push", &state_mgr_t::push)
.def("pop", &state_mgr_t::pop)
.def("count", &state_mgr_t::count);
scope().attr("states") = boost::python::object(boost::python::ptr(&states));
}
The states object is referencing a global value, states:
extern state_mgr_t states;
I can run the following script lines from within my program:
from mandala import states
states.count()
> 0
All of that is fine and whatnot, but I was expecting that running this python script would affect the actual state of the program that is running it. It appears as though Python is actually just dealing with it's own instance of states and not affecting the parent program.
Now I'm wondering if I've completely misunderstood what Boost.Python is capable of; I was expecting something similar to Lua, where I could modify the C++ program via scripts.
Is this not possible? Or am I doing something very wrong?
Thank you in advance!
If you are embedding Python into your C++ program, it should be possible to access the instance from your script. Obviously, I don't have your full code, but have you tried something like this?
PyImport_AppendInittab("mandala", &initmandala);
Py_Initialize();
try {
object main_module = import("__main__");
object main_namespace = main_module.attr("__dict__");
main_namespace.attr("states") = ptr(&states);
object ignored = exec("print states.count()", main_namespace);
} catch(const error_already_set&) {
PyErr_Print();
}

Loading a document on OpenOffice using an external Python program

I'm trying to create a python program (using pyUNO ) to make some changes on a OpenOffice calc sheet.
I've launched previously OpenOffice on "accept" mode to be able to connect from an external program. Apparently, should be as easy as:
import uno
# get the uno component context from the PyUNO runtime
localContext = uno.getComponentContext()
# create the UnoUrlResolver
resolver = localContext.ServiceManager.createInstanceWithContext(
"com.sun.star.bridge.UnoUrlResolver", localContext)
# connect to the running office
ctx = resolver.resolve("uno:socket,host=localhost,port=2002;"
"urp;StarOffice.ComponentContext")
smgr = ctx.ServiceManager
# get the central desktop object
DESKTOP =smgr.createInstanceWithContext("com.sun.star.frame.Desktop", ctx)
#The calling it's not exactly this way, just to simplify the code
DESKTOP.loadComponentFromURL('file.ods')
But I get an AttributeError when I try to access loadComponentFromURL. If I make a dir(DESKTOP), I've see only the following attributes/methods:
['ActiveFrame', 'DispatchRecorderSupplier', 'ImplementationId', 'ImplementationName',
'IsPlugged', 'PropertySetInfo', 'SupportedServiceNames', 'SuspendQuickstartVeto',
'Title', 'Types', 'addEventListener', 'addPropertyChangeListener',
'addVetoableChangeListener', 'dispose', 'disposing', 'getImplementationId',
'getImplementationName', 'getPropertySetInfo', 'getPropertyValue',
'getSupportedServiceNames', 'getTypes', 'handle', 'queryInterface',
'removeEventListener', 'removePropertyChangeListener', 'removeVetoableChangeListener',
'setPropertyValue', 'supportsService']
I've read that there are where a bug doing the same, but on OpenOffice 3.0 (I'm using OpenOffice 3.1 over Red Hat5.3). I've tried to use the workaround stated here, but they don't seems to be working.
Any ideas?
It has been a long time since I did anything with PyUNO, but looking at the code that worked last time I ran it back in '06, I did my load document like this:
def urlify(path):
return uno.systemPathToFileUrl(os.path.realpath(path))
desktop.loadComponentFromURL(
urlify(tempfilename), "_blank", 0, ())
Your example is a simplified version, and I'm not sure if you've removed the extra arguments intentionally or not intentionally.
If loadComponentFromURL isn't there, then the API has changed or there's something else wrong, I've read through your code and it looks like you're doing all the same things I have.
I don't believe that the dir() of the methods on the desktop object will be useful, as I think there's a __getattr__ method being used to proxy through the requests, and all the methods you've printed out are utility methods used for the stand-in object for the com.sun.star.frame.Desktop.
I think perhaps the failure could be that there's no method named loadComponentFromURL that has exactly 1 argument. Perhaps giving the 4 argument version will result in the method being found and used. This could simply be an impedance mismatch between Python and Java, where Java has call-signature method overloading.
This looks like issue 90701: http://www.openoffice.org/issues/show_bug.cgi?id=90701
See also http://piiis.blogspot.com/2008/10/pyuno-broken-in-ooo-30-with-system.html and http://udk.openoffice.org/python/python-bridge.html

Categories