Google ORTools Type Mismatch (Python) - python-3.x

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

Related

What to do when a code review tool declares unmatched types?

I am working on developing a large-scale Python (backend) project. I was working with a firm that does extensive testing, and they built the frontend and test tools. Before every deploy, all the tools (like linters) are run regularly.
I had put down the code for a while, and now it fails many tests. Some of these are deprecation warnings for features or syntax soon to be deprecated, and they note they started classifying those as warnings (to later become errors) starting January 1, 2020, so I know they make dynamic changes in the tools themselves.
My problem is a bunch of code that used to pass no longer does. And the error is always the same: if I have a line that looks like so, I get an error that says something along the lines of "error: may not use operator '-' with incompatible types; a and b are of types numpy.array and NoneType":
x = a - b
This gets fixed by making the code super-messy with this sort of fix:
x = a.astype(float) - b.astype(float)
It's even worse because in the actual code there are 3 variables, all doing addition and subtraction with a 'c' that is an integer array kicking around along with the two numpy arrays. But then the code goes from:
x = a - b - c
to:
x = a.astype(float) - b.astype(float) - c.astype(float)
And this won't work since int's don't have an astype method. The error looks like this now:
File "/home/engine.py", line 165, in Foo
lower_array[t].astype(float)) / num_values.astype(float)
AttributeError: 'NoneType' object has no attribute 'astype'
Thus, I end up with:
x = a.astype(float) - b.astype(float) - float(c)
This is all extraordinarily cumbersome and nasty casting that is required, and makes the code impossible to read.
The odd thing to me is that all three arrays were instantiated as numpy arrays, i.e.,:
a=numpy.array(_a)
b=numpy.array(_b)
c=numpy.array(_c)
When I ask the code to put output to stdout the type of all three vars, they all say . Yet, the next line of code blows up and dumps, saying "Attribute error: 'NoneType' object has no attribute 'astype'"
I can't fathom how a static code analyzer determines the types - other than as numpy.ndarray type - since Python uses duck-typing. Thus, the type could change dynamically. But that's not the case here; all three vars are identified as numpy.ndarray type, but "z = a - b - c" fails.
Anyone understand what's going on here?
After much work, the answer is to ignore the linter. Readable code is the object, not code that satisfies a linter.

Timeout value must be int,Float or None

I was trying setting value of backoff_factor in python code using environment variable.
After that i am trying to call backoff_factor from my crateDB code and it is throwing the following error: ValueError: Timeout value connect was backoff_factor, but it must be an int, float or None.
I wanted the retry interval between retries to connect to database.
Please refer below links for the same:
I am setting export 'backoff_factor'=0.1 here: https://github.com/smartsdk/ngsi-timeseries-api/blob/master/setup_dev_env.sh
Using backoff_factor in crate.py file in my source code using os module: https://github.com/smartsdk/ngsi-timeseries-api/blob/dc565af24b303a94f7c298b2567e62487088de3b/src/translators/crate.py#L64
def setup(self):
environ.get('backoff_factor')
url = "{}:{}".format(self.host, self.port)
self.conn = client.connect([url],'backoff_factor')
self.cursor = self.conn.cursor()
I also tried upgrading urllib3 and request version but not worked out.
Any help will be appreciable.Thanks
The error message seems clear: backoff_factor must be a number or None and you're passing a string:
environment variables are strings, always, you have to convert them to numbers explicitly, Python rarely performs implicit type conversions.
you're not even passing the backoff_factor you defined to connect here, environ.get() returns the value but you're not assigning it, and then you're passing the literal string 'backoff_factor' to connect.
your use of the API also seems odd, I can't find any backoff_factor parameter in the cratedb documentation but given the style if there were one it'd be a keyword parameter (aka client.connect(url, backoff_factor=...))

Passing argument to lua function after evaluating function in string

I have functions process and matrix. The following code works
process(matrix({{2,4,6},{8,10,12},{14,16,20}}))
However the following doesn't work.
n='matrix({{2,4,6},{8,10,12},{14,16,20}})'
process(n)
It throws some error. The reason is obvious that process takes n as string rather than the output of the function matrix. So the basic difficulty involved here is about evaluating string from variable n and then give it as argument to the function process. Here loadstring function is of no use as matrix is local function and can't be referred from loadstring.
Is there any work around for this? I hope that I have clearly stated the problem here. It is about evaluating (or unloading) string and then passing it as argument to another function. Any help will be appreciated. Thanks.
as matrix is local function
Lua takes local declarations seriously. If a variable is declared local, it can only be accessed by code which is statically within the local scope of that variable. Strings which you later turn into code are not statically in the local scope and therefore cannot access local variables.
Now, with Lua 5.2+, you can provide load with a second parameter, a table which represents the global environment against which that Lua chunk will be built. If that table contains a matrix value, then the loaded string can access it. For Lua 5.1, you'd have to use setfenv on the function returned to load to accomplish a similar effect. The Lua 5.2+ method would look like this:
local env = {matrix = matrix}
local func = load("return matrix({{2,4,6},{8,10,12},{14,16,20}})", nil, "t", env)
process(func())
Note the following:
You must create an explicit table which is the global environment. There's nothing you can pass that says "make my locals available"; you have to put every local you'd like to access there. Which is, generally speaking, why you pass these things as parameters or just make them globals.
You explicitly need the "return " there if you want to get the results of the call to matrix.
You have to call the function. Functions are values in Lua, so you can freely pass them around. But if you want to pass the results of a function to another function, you have to actually call it.

How to enforce variable typing in Named Tuple in Python?

I am following this tutorial on named tuple with specification of variable types. However, I modified the code (below), and even if I enter values of wrong types, there was no error message or programming break as a result. I understand you can write your own try/except to raise error exception, but is there a readily-available solution/syntax to enforce users entering the right type of variables.
from typing import NamedTuple
class Pet(NamedTuple):
pet_name: str
pet_type: str
def __repr__(self):
return f"{self.pet_name}, {self.pet_type}"
cleons_pet = Pet('Cotton', 'owl')
print('cleons_pet: ', cleons_pet)
cleons_pet_v2 = Pet(222, 1)
print('cleons_pet_v2: ', cleons_pet_v2)
# Output
cleons_pet: Cotton, owl
cleons_pet_v2: 222, 1
[Finished in 0.1s]
The type hints in python will not be evaluated by python itself! See PEP484
While these annotations are available at runtime through the usual annotations attribute, no type checking happens at runtime. Instead, the proposal assumes the existence of a separate off-line type checker which users can run over their source code voluntarily.
There are at least two projects which offer offline type checking (mypy and pyre). You should definitely use them if you are using type hints in your project.
If you want to validate the input while running the application, you have to either convince the offline type checkers by validating the data by yourself or use a third-party library. I know of attrs, where you can use validators or type annotations for online validation.

python3 how to define ctypes struct for return type from imported library

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.

Resources