I'm trying to get a reference to a object in cython.
The following code compiles without problems:
cdef vector[int] a
a.push_back(1)
cdef vector[int] & b=a
However, as I add the following line:
b.push_back(1)
The compiler complains that b has been declared as a reference but not initialized.
How should I initialise a reference in cython?
(the documentation is a bit vague on the usage of references in cython)
Why not doing this :
cdef vector[int] a
a.push_back(1)
cdef vector[int] *b=&a
b[0].push_back(1)
b.push_back(2) # Works too, I gess
Related
I am attempting to use Google's ORTools in Python to run an optimization. The catch is that the calculations I am trying to optimize have to be accessed through COM, as they are contained in a proprietary piece of external software. Is there any way to accomplish this?
The COM Object accepts integer or float values as inputs, but ORTools passes variables as variable objects, so the COM object is unable to use them. I attempted to get around this by using the solution_value() method, as this was the only method I could find to access variable values, but this issues the following error message and causes the solver to stop working:
"The model has been changed since the solution was last computed. MPSolverInterface:: sync_status_ = 0".
If I just pass the variable to the COM Object, I get the following error:
"Exception has occurred: TypeError. must be real number, not Variable."
See below for my example code:
from ortools.linear_solver import pywraplp
import win32com.client as win32
Program = win32.Dispatch("CalcProgram")
def Calculations(x,y):
Program.SetValue(x)
Program.SetValue(y.solution_value())
return Program.GetValue(Z)
solver = pywraplp.Solver.CreateSolver('SCIP')
x = solver.IntVar(1,25)
y = solver.IntVar(30,60)
solver.Minimize(Calculations(x,y))
status = solver.Solve()
You are missing the point of the linear solver and how to use it.
solver.Minimize() takes a linear expression, that is a python object built with overloaded +, -, * operators and variables and constants.
a valid call could be:
solver.Minimize(x + 2 * y)
Furthermore, solution_value() can only called after a successful Solve().
You should look at python samples to see how programs are structured.
See https://github.com/google/or-tools/blob/stable/ortools/linear_solver/samples/simple_mip_program.py
I actually don't have any question about my code but i use a ide named pycharm while running my code i don't get any error but my ide gives me a warning why is that so?
Here's my code :
def hi():
global d
d = 5
hi()
print(d)
My code works fine but my ide gives me a warning at line 2 of my code which is Global variable 'd' is undefined at the module level.
Did i do anything wrong in my code i just created a global variable through a function and accesed it outside the function.
does anyone know why this is happening?
As you said there is no error, just a warning. You can look up the different inspection severity levels here
I quote from this website:
Warning: marks code fragments that might produce bugs or require enhancement.
So Pycharm is trying to tell you that using global in this way could lead to bugs down the line, especially if your code gets more complicated. This warning appears so that you get a change to rethink how your code works and that there are maybe better ways to achieve the same goal.
In this case the warning comes from the fact that d is undefined at the module level, which can be fixed by defining it, e.g. at the top.
d = 11
In general there are many reason why one should avoid the global keyword (see discussion here), but if you know why you are using it then its fine.
Global variables are never recommended as they could produce errors in the future as see Why are global variables evil?
your code should be
def hi():
return 5
print(hi())
If you just want to get rid of the warning "Global variable 'd' is undefined at the module level."
You could declare the desired global variable and don't not assign a value (None) with type hints.
d :str
d :str
def hi():
global d
d = 5
hi()
print(d)
Does PyIntObject still in python3.x source code,or has it been replaced by PyLongObject? I can't find the code as follows:
typedef struct {
PyObject_HEAD
long ob_ival;
} PyIntObject;
From https://docs.python.org/3.2/howto/cporting.html (long/int Unification):
Python 3 has only one integer type, int(). But it actually corresponds to Python 2’s long() type–the int() type used in Python 2 was removed. In the C-API, PyInt_* functions are replaced by their PyLong_* equivalents.
The best course of action here is using the PyInt_* functions aliased to PyLong_* found in intobject.h. The abstract PyNumber_* APIs can also be used in some cases.
Please check also the following discussion:
How does Python manage int and long?
I am not sure what the problem is here, so I don't really know how I should call the subject for that question. Please offer a better subject if you know.
The code below is a extrem simplified example of the original one. But it reproduce the problem very nice. After the call of test() foo should be sieben.
I think I didn't know some special things about scopes of variables in Python. This might be a very good problem to learn more about that. But I don't know on which Python topic I should focus here to find a solution for my own.
#!/usr/bin/env python3
def test(handlerFunction, **handlerArgs):
handlerFunction(**handlerArgs)
def myhandler(dat):
print('dat={}'.format(dat))
dat = 'sieben'
print('dat={}'.format(dat))
foo = 'foo'
test(myhandler, dat=foo)
print('foo={}'.format(foo))
Of course I could make foo a global variable. But that is not the goal. The goal is to carry this variable inside and through sub-functions of different levels and bring the result back. In the original code I use some more complexe data structures with **handlerArgs.
A solution could be to use a list() as an mutable object holding the immutable one. But is this really elegant or pythonic?
#!/usr/bin/env python3
def test(handlerFunction, **handlerArgs):
handlerFunction(**handlerArgs)
def myhandler(dat):
print('dat={}'.format(dat))
# MODIFIED LINE
dat[0] = 'sieben'
print('dat={}'.format(dat))
# MODIFIED LINE
foo = ['foo']
test(myhandler, dat=foo)
print('foo={}'.format(foo))
The ** syntax has nothing to do with this. dat is local to myhandler, and assigning it doesn't change the global variable with the same name. If you want to change the module variable from inside the function, declare the variable as global at the beginning of the function body:
def myhandler(): # you don't need to pass dat as argument
global dat
print('dat={}'.format(dat))
dat = 'sieben'
print('dat={}'.format(dat))
Here's a relevant portion from the docs:
If a name binding operation occurs anywhere within a code block, all uses of the name within the block are treated as references to the current block. This can lead to errors when a name is used within a block before it is bound. This rule is subtle. Python lacks declarations and allows name binding operations to occur anywhere within a code block. The local variables of a code block can be determined by scanning the entire text of the block for name binding operations.
If the global statement occurs within a block, all uses of the name specified in the statement refer to the binding of that name in the top-level namespace. Names are resolved in the top-level namespace by searching the global namespace, i.e. the namespace of the module containing the code block, and the builtins namespace, the namespace of the module builtins. The global namespace is searched first. If the name is not found there, the builtins namespace is searched. The global statement must precede all uses of the name.
After your edit the question reads as: "how do I mutate an immutable object?"
Well, I think you've guessed it: you don't. Using a mutable object in this manner seems reasonable to me.
I'm trying to use ctypes to use fann (a neural network library written in C) in python3. Here is my abridged code so far:
from ctypes import *
cdll.LoadLibrary("/usr/local/lib/libdoublefann.dylib")
fann = CDLL("/usr/local/lib/libdoublefann.dylib")
# Call fann to create a neural network
nn = fann.fann_create_from_file(b'/Users/xxxxx/Code/fanncode/net/nnf_25_1339802027.net')
# this outputs 3909360
print(nn)
If I try and call any other functions in the fann library against the nn variable, which should now be a fann neural network, I either get Segmentation fault: 11 or AttributeError: 'int' object has no attribute 'getMSE' (for example). I think my problem is that according to the ctypes documentation, the variable nn is ending up being an int, whereas the fann documentation for the function fann_create_from_file states:
FANN_EXTERNAL struct fann *FANN_API fann_create_from_file(const char * configuration_file)
So I think I need to declare:
class FANN_API(Structure):
<fields and things which I don't know what they should be>
And then do:
fann.fann_create_from_file.restype = FANN_API
My problem is that I can't find what the struct FANN_API should be. Line 130 of fann.h states #define FANN_API but thats it, no definition or anything follows it.
Am I correct in my guess about needing to define the struct? If so, then how can I find out the format of it to declare in the python code? If not then can anybody suggest what I might need to do/what to read to get my code to work?
Thanks!
You can tell ctypes the arguments and return codes of functions. You should be able to get away with c_void_p (void*) as the type unless you have some reason to manipulate the contents of the structure:
fann.fann_create_from_file.restype = c_void_p
fann.fann_create_from_file.argtypes = [c_char_p]
Note that struct fann * is the return type of your function. FANN_API represents the calling convention. You've said it is defined as #define FANN_API. Being defined as nothing means the default calling convention, so your use of CDLL should be correct.
If you need to define something more specific, post the definition of struct fann.