How to put a constraint on the dual variable of the another constraint in Pyomo? - constraints

I am working on an economic model and I need to put a cap on the dual of one of the constraints but I have errors. I would be thankful if someone could help.
At the beginning of the code, I put this line:
model.dual = pyo.Suffix(direction=pyo.Suffix.IMPORT_EXPORT)
Here is the constraint I have defined on the dual:
model.adequacy_constraint = \ pyo.Constraint(model.h, rule=adequacy_constraint_rule) def lost_load_rule(model, h):\ return model.dual[model.adequacy_constraint[h]]< 1e9 model.voll_constraint = \ pyo.Constraint(model.h, rule=lost_load_rule)
here is the error:
return model.dual[model.adequacy_constraint[h]]< 1e9 File "C:\Users\Maryam\PycharmProjects\pythonProject1\venv\lib\site-packages\pyomo\common\collections\component_map.py", line 96, in __getitem__ raise KeyError("Component with id '%s': %s" KeyError: "Component with id '2384738399616': adequacy_constraint[0]"

You can't put restrictions on the duals in traditional optimization models. If you really need to, and dualizing the model is not an option, you may want to look into Complementarity and MPEC models.

Related

Rename Dexterity object (id) after copy

It's simple to choose the object ID at creation time with INameChooser.
But we also want to be able to choose the object ID after a clone (and avoid copy_of in object ID).
We tried several different solutions :
subscribers on events :
OFS.interfaces.IObjectClonedEvent
zope.lifecycleevent.interfaces.IObjectAddedEvent
...
manage_afterClone method on content class
Every time, we get a traceback because we changed the ID "too soon". For example when using Plone API :
File "/Users/laurent/.buildout/eggs/plone.api-2.0.0a1-py3.7.egg/plone/api/content.py", line 256, in copy
return target[new_id]
File "/Users/laurent/.buildout/eggs/plone.folder-3.0.3-py3.7.egg/plone/folder/ordered.py", line 241, in __getitem__
raise KeyError(key)
KeyError: 'copy_of_87c7f9b7e7924d039b832d3796e7b5a3'
Or, with a Copy / Paste in the Plone instance :
Module plone.app.content.browser.contents.paste, line 42, in __call__
Module OFS.CopySupport, line 317, in manage_pasteObjects
Module OFS.CopySupport, line 229, in _pasteObjects
Module plone.folder.ordered, line 73, in _getOb
AttributeError: 'copy_of_a7ed3d678f2643bc990309cde61a6bc5'
It's logical, because the ID is stored before events notification / manage_afterClone call for later use.
Even defining a _get_id on containers cannot work to define the ID, because we don't have the object to get attributes from (and generate the ID).
But then, how could we achieve this in a clean way ?
Please tell me there is a better solution than redefining _pasteObjects (OFS.CopySupport) !
Thank you for your inputs !
So unfortunately not...
But you can access the original object from within _get_id.
For example:
from OFS.CopySupport import _cb_decode
from plone import api
...
def _get_id(self, id_):
# copy_or_move => 0 means copy, 1 means move
copy_or_move, path_segments = _cb_decode(self.REQUEST['__cp']
source_path = '/'.join(path_segments[0]) # Imlement for loop for more than one copied obj.
app = self.getPhysicalRoot()
# access to source obj
source_obj = app.restrictedTraverse(source_path)
# Do whatever you need - probably using INameChooser
....
To have a canonical way of patching this I use collective.monkeypatcher
Once installed add the following in ZCML:
<include package="collective.monkeypatcher" />
<monkey:patch
class="OFS.CopySupport.CopyContainer"
original="_get_id"
replacement="patches.patched_get_id"
/>
Where patches.py is your module containing the new method patched_get_id, which replaces _get_id.
I'm sorry I don't have better news for you, but this is how I solved a similar requirement.
This code (patched _get_id) adds a counter at the end of a id if already there.
def patched_get_id(self, id_)
match = re.match('^(.*)-([\d]+)$', id_)
if match:
id_ = match.group(1)
number = int(match.group(2))
else:
number = 1
new_id = id_
while new_id in self.objectIds():
new_id = '{}-{}'.format(id_, number)
number += 1
return new_id

Inserting data into SQLite database fails with sqlite3.InterfaceError: Error binding parameter 0 - probably unsupported type

I have looked through quite a lot of the ones raised on this site and unless I am being dense ( Which who knows), I don't think they quite replicate my issue.
First let me start with some Code snippets
table
CREATE TABLE IF NOT EXISTS moves(
ID INTEGER PRIMARY KEY AUTOINCREMENT,
name char(20),
type char(10),
category char(10),
desc char(200),
share char(3),
priority char(5),
damage_dice char(5),
cool_down char(8),
accuracy char(100),
effect char(200),
move_target char(50),
makes_contact char(3),
contest_cat char(10)
)''')
The insert function
def insert_moves(move):
c = dbConn.cursor()
statement = '''insert into moves values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)'''
try:
c.execute(statement,(move[0], str(move[1]), str(move[2]), str(move[3]), str(move[4]),
str(move[5]), str(move[6]), str(move[7]), str(move[8]), str(move[9]), str(move[10]),
str(move[11]), str(move[12]), str(move[13]),))
dbConn.commit()
return True, ''
except Exception as e:
return False, e
Now, let me show you the stack trace and as part of that, you will see the printed output of move before its passed into the datebase function.
Now, this is the output
[1, 'Attack Order', 'Bug', 'Physical', 'The user calls out its underlings to pummel the target.', 'Yes', '-', '1d6', '1 Turn', '100', 'Attack Order deals damage and has an increased critical hit ratio of 50 percent', 'Targets a single adjacent Pokemon.', 'No', 'Clever']
Ignoring exception in command update_moves:
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/discord/ext/commands/core.py", line 85, in wrapped
ret = await coro(*args, **kwargs)
File "/projects/pokebot/gsheet.py", line 59, in update_moves
result, error2 = db.insert_moves(moves)
File "/projects/pokebot/db.py", line 103, in insert_moves
c.execute(statement,(move[0], str(move[1]), str(move[2]), str(move[3]), str(move[4]), str(move[5]), str(move[6]), str(move[7]), str(move[8]), str(move[9]), str(move[10]), str(move[11]), str(move[12]), str(move[13]),))
sqlite3.InterfaceError: Error binding parameter 0 - probably unsupported type.
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/discord/ext/commands/bot.py", line 903, in invoke
await ctx.command.invoke(ctx)
File "/usr/local/lib/python3.6/site-packages/discord/ext/commands/core.py", line 859, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "/usr/local/lib/python3.6/site-packages/discord/ext/commands/core.py", line 94, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: InterfaceError: Error binding parameter 0 - probably unsupported type.
I have tried a few things such as removing random percent signs in case that was the issue, or changing Pokémon to Pokemon. But I don't see what the issue is. A lot of the others were all about people sending in things like Lists or objects to insert instead of some string/int object and I don't believe that to be the issue here. Is there anything that stands out?
So...this was definitely my fault. And if I had posted the function that called the insert, I would have seen it. I guess its just a friday afternoon and my brain is tired.
print(move)
result, error2 = db.insert_moves(move)
this was written as
print(move)
result, error2 = db.insert_moves(moves)
Where moves is iterated over so that I can do some work on it. Honestly, this was my fault completely. Oh well, I think the lesson is....on the insert function, if you are getting this error, check the type of the value passed. Which honestly, I should have done by now..but I'll just chalk it up to Friday afternoon.

Google Earth Engine download problems, is this caused by immutable server side objects?

I have a function that will download an image collection as a TFrecord or a geotiff.
Heres the function -
def download_image_collection_to_drive(collection, aois, bands, limit, export_format):
if collection.size().lt(ee.Number(limit)):
bands = [band for band in bands if band not in ['SCL', 'QA60']]
for aoi in aois:
cluster = aoi.get('cluster').getInfo()
geom = aoi.bounds().getInfo()['geometry']['coordinates']
aoi_collection = collection.filterMetadata('cluster', 'equals', cluster)
for ts in range(1, 11):
print(ts)
ts_collection = aoi_collection.filterMetadata('interval', 'equals', ts)
if ts_collection.size().eq(ee.Number(1)):
image = ts_collection.first()
p_id = image.get("PRODUCT_ID").getInfo()
description = f'{cluster}_{ts}_{p_id}'
task_config = {
'fileFormat': export_format,
'image': image.select(bands),
'region': geom,
'description': description,
'scale': 10,
'folder': 'output'
}
if export_format == 'TFRecord':
task_config['formatOptions'] = {'patchDimensions': [256, 256], 'kernelSize': [3, 3]}
task = ee.batch.Export.image.toDrive(**task_config)
task.start()
else:
logger.warning(f'no image for interval {ts}')
else:
logger.warning(f'collection over {limit} aborting drive download')
It seems whenever it gets to the second aoi it fails, Im confused by this as if ts_collection.size().eq(ee.Number(1)) confirms there is an image there so it should manage to get product id from it.
line 24, in download_image_collection_to_drive
p_id = image.get("PRODUCT_ID").getInfo()
File "/lib/python3.7/site-packages/ee/computedobject.py", line 95, in getInfo
return data.computeValue(self)
File "/lib/python3.7/site-packages/ee/data.py", line 717, in computeValue
prettyPrint=False))['result']
File "/lib/python3.7/site-packages/ee/data.py", line 340, in _execute_cloud_call
raise _translate_cloud_exception(e)
ee.ee_exception.EEException: Element.get: Parameter 'object' is required.
am I falling foul of immutable server side objects somewhere?
This is a server-side value, problem, yes, but immutability doesn't have to do with it — your if statement isn't working as you intend.
ts_collection.size().eq(ee.Number(1)) is a server-side value — you've described a comparison that hasn't happened yet. That means that doing any local operation like a Python if statement cannot take the comparison outcome into account, and will just treat it as a true value.
Using getInfo would be a quick fix:
if ts_collection.size().eq(ee.Number(1)).getInfo():
but it would be more efficient to avoid using getInfo more than needed by fetching the entire collection's info just once, which includes the image info.
...
ts_collection_info = ts_collection.getInfo()
if ts_collection['features']: # Are there any images in the collection?
image = ts_collection.first()
image_info = ts_collection['features'][0] # client-side image info already downloaded
p_id = image_info['properties']['PRODUCT_ID'] # get ID from client-side info
...
This way, you only make two requests per ts: one to check for the match, and one to start the export.
Note that I haven't actually run this Python code, and there might be some small mistakes; if it gives you any trouble, print(ts_collection_info) and examine the structure you actually received to figure out how to interpret it.

initialization of variable in pre in Modelica

I wrote the codes in Modelica as below:
model TestIniitial
extends Modelica.Icons.Example;
parameter Integer nWri= 2;
Real u[nWri](each start= 10, fixed=false);
Real uPre[nWri];
parameter Real _uStart[nWri] = fill(10, nWri);
parameter Modelica.SIunits.Time startTime = 0;
parameter Modelica.SIunits.Time samplePeriod = 1;
Boolean sampleTrigger "True, if sample time instant";
initial equation
u[1] = 1;
u[2] = 2;
equation
sampleTrigger = sample(startTime, samplePeriod);
when sampleTrigger then
for i in 1: nWri loop
uPre[i] = pre(u[i]);
end for;
end when;
for i in 1:nWri loop
u[i] = (i+1)*time;
end for;
end TestIniitial;
Basically I want to initialize the u before simulation. However, I got below complaints(the initialization of u is over-specified) from translation:
The Modelica Language Specification 3.2.1 specifies that if a real variable, v,
is appearing in an expression as pre(v), but not assigned by a when equation,
then the equation v = pre(v) should be added to the initialization problem.
For this problem the following equations were added:
u[1] = pre(u[1]);
u[2] = pre(u[2]);
I can't understand the complaints since pre(v) was assigned in when equation already. What can I do if I want to initialize the u in above codes?
Thanks.
Looking at this, my guess is that the error message is trying to provide you some diagnostics but it is incorrect about the source. I suspect (again, I do not know for sure) that it sees the fact that pre(u) appears in the model and that there is an initialization problem and assumes a specific issue.
My guess is that the issue stems from the fact that you have fixed=true set on u. I see no reason to do that and my guess is that it will lead to too many constraints on the initialization problem as well. Get rid of the fixed=true and see what happens. Report back if that doesn't address the problem.
Good luck.

incremental select using id from SQLite in Twisted

I am trying to select data from a table in SQLite one row ONLY at a time for each call to the function, and I want the row to increment on each call (self.count is initialized elsewhere and 'line' is irrelevant here) I am using an adbapi connection pool in Twisted to connect to the DB. Here is the code I have tried:
def queryBTData4(self,line):
self.count=self.count+1
uuId=self.count
query="SELECT co2_data, patient_Id FROM btdata4 WHERE uid=:uid",{"uid": uuId}
d = self.dbpool.runQuery(query)
return d
This code works if I just set uid=1 or any other number in the DB (I used autoincrement for uid when I created the DB) but when I try to assign a value to uid (i.e. self.count via uuId) it reports that the operator has to be string or unicode.(I have tried both but it does not seem to help) However, I know that the query statement above works just fine in a previous program when I use a cursor and the execute command but I cannot see why it does not work here. I have tried all sorts of combinations and searched for a solution but have not found anything yet that works.(I have also tried the statement with brackets and other forms)
Thanks for any help or advice.
Here is the entire code:
from twisted.internet import protocol, reactor
from twisted.protocols import basic
from twisted.enterprise import adbapi
import sqlite3, time
class ServerProtocol(basic.LineReceiver):
def __init__(self):
self.conn = sqlite3.connect('biomed2.db',check_same_thread=False)
self.dbpool = adbapi.ConnectionPool("sqlite3" , 'biomed2.db', check_same_thread=False)
def connectionMade(self):
self.sendLine("conn made")
factory = protocol.ClientFactory()
factory.protocol = ClientProtocol
factory.originator = self
reactor.connectTCP('localhost', 1234, factory)
def lineReceived(self, line):
self._received = line
self.insertBTData4(self._received)
self.sendLine("line recvd")
def forwardLine(self, recipient):
recipient.sendLine(self._received)
def insertBTData4(self,data):
print "data in insert is",data
chx=data
PID=2
device_ID=5
query="INSERT INTO btdata4(co2_data,patient_Id, sensor_Id) VALUES ('%s','%s','%s')" % (chx, PID, device_ID)
dF = self.dbpool.runQuery(query)
return dF
class ClientProtocol(basic.LineReceiver):
def __init__(self):
self.conn = sqlite3.connect('biomed2.db',check_same_thread=False)
self.dbpool = adbapi.ConnectionPool("sqlite3" , 'biomed2.db', check_same_thread=False)
self.count=0
def connectionMade(self):
print "server-client made connection with client"
self.factory.originator.forwardLine(self)
#self.transport.loseConnection()
def lineReceived(self, line):
d=self.queryBTData4(self)
d.addCallbacks(self.sendData,self.printError )
def queryBTData4(self,line):
self.count=self.count+1
query=("SELECT co2_data, patient_Id FROM btdata4 WHERE uid=:uid",{"uid": uuId})
dF = self.dbpool.runQuery(query)
return dF
def sendData(self,line):
data=str(line)
self.sendLine(data)
def printError(self,error):
print "Got Error: %r" % error
error.printTraceback()
def main():
factory = protocol.ServerFactory()
factory.protocol = ServerProtocol
reactor.listenTCP(4321, factory)
reactor.run()
if __name__ == '__main__':
main()
The DB is created in another program, thus:
import sqlite3, time, string
conn = sqlite3.connect('biomed2.db')
c = conn.cursor()
c.execute('''CREATE TABLE btdata4
(uid INTEGER PRIMARY KEY, co2_data integer, patient_Id integer, sensor_Id integer)''')
The main program takes data into the server socket and inserts into DB. On the client socket side, data is removed from the DB one line at a time and sent to an external server. The program also has the ability to send data from the server side to the client side if required but I am not doing so here at the moment.
In queryBTData(), every time the function is called the count increments and I assign that value to uuId, which I then pass to the query. I have had this query statement working in a program where I do not use the adbapi but it does not seem to work here. I hope this is clear enough but if not please let me know and I will try again.
EDIT:
I have modified the program to take one row from the DB at a time (see queryBTData() below) but have come across another problem.
def queryBTData4(self,line):
self.count=self.count+1
xuId= self.count
#xuId=10
return self.dbpool.runQuery("SELECT co2_data FROM btdata4 WHERE uid = ?",xuId)
#return self.dbpool.runQuery("SELECT co2_data FROM btdata4 WHERE uid = 10")
When the count gets to 10 I get an error (which I will post below) which states that: "Incorrect number of bindings supplied. The current statement uses 1, and there are 2 supplied"
I have tried setting xuId to 10 (see commented out line xuId=10) but I still get the same error. However, if I switch the return statements (to commented out return) I do indeed get correct row with no error. I have tried converting xuId to unicode but that makes no difference, I still get the same error. Basically, if I I set uid in the return statement to 10 or more (commented out return) it works, but if I set uid to xuId (i.e. uid=?,xuId) in the first return, it only works when xuId is below 10. The API documentation, as far as I can tell, gives no clue as to why this occurs.(I have also disabled the insert into DB to eliminate this and checked the SQLite3_ limit, which is 999)
Here are the errors I am getting when using the first return statement.
Got Error: <twisted.python.failure.Failure <class 'sqlite3.ProgrammingError'>>
Traceback (most recent call last):
File "c:\python26\lib\threading.py", line 504, in __bootstrap
self.__bootstrap_inner()
File "c:\python26\lib\threading.py", line 532, in __bootstrap_inner
self.run()
File "c:\python26\lib\threading.py", line 484, in run
self.__target(*self.__args, **self.__kwargs)
--- <exception caught here> ---
File "c:\python26\lib\site-packages\twisted\python\threadpool.py", line 207, i
n _worker
result = context.call(ctx, function, *args, **kwargs)
File "c:\python26\lib\site-packages\twisted\python\context.py", line 118, in c
allWithContext
return self.currentContext().callWithContext(ctx, func, *args, **kw)
File "c:\python26\lib\site-packages\twisted\python\context.py", line 81, in ca
llWithContext
return func(*args,**kw)
File "c:\python26\lib\site-packages\twisted\enterprise\adbapi.py", line 448, i
n _runInteraction
result = interaction(trans, *args, **kw)
File "c:\python26\lib\site-packages\twisted\enterprise\adbapi.py", line 462, i
n _runQuery
trans.execute(*args, **kw)
sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current sta
tement uses 1, and there are 2 supplied.
Thanks.
Consider the API documentation for runQuery. Next, consider the difference between these three function calls:
c = a, b
f(a, b)
f((a, b))
f(c)
Finally, don't paraphrase error messages. Always quote them verbatim. Copy/paste whenever possible; make a note when you've manually transcribed them.

Resources