Changing parameter values inside a loup - pyomo

I have created a parameter to report values after each instance solve in an iterative program.I wan't my parameter to be indexed by the set that defines the number of iteration and have two other free indexes like so:
model.report=Param(model.iter,[],[])
I then wan't to create a function,that will be called into a while loop and that will create my model,solve an instance and give some values to some variables, whose names will be used as indexes in my report parameter, like so:
report(model.iter,'cost',model.i)=model.cost[i]
Where model.cost is my cost variable indexed by set i.
Is it possible to do that?

You are better off simply making model.report a Python dict. Then you can assign it entries with whatever keys you like:
model.report = dict()
...
for j in range(10):
# assumes model.i is a simple built-in type and not a Param
# (otherwise you would need to use model.i.value)
model.report[j,'cost',model.i] = model.cost[j]
There is no reason to use a Param in this context unless you are using those values in some kind of expression and you want to be able to update the expression at a later time by changing the value of the Param (i.e., you would use mutable=True when you declare the Param).

Related

Get part of django model depending on a variable

My code
PriceListItem.objects.get(id=tarif_id).price_eur
In my settings.py
CURRENCY='eur'
My Question:
I would like to pick the different info depending on the CURRENCY variable in settings.py
Example:
PriceListItem.objects.get(id=tarif_id).price_+settings.CURRENCY
Is it possible?
Sure. This has nothing to do with Django actually. You can reach the instance's attribute through pure Python:
getattr(PriceListItem.objects.get(id=tarif_id), 'price_'+settings.CURRENCY)
Note it might be a better idea to have a method on the model which accepts the currency as a parameter and returns the correct piece of data (through the line I wrote above, for example).
I think this should work
item = PriceListItem.objects.get(id=tarif_id)
value = getattr(item, price_+settings.CURRENCY)
In case you are only interested in that specific column, you can make the query more efficient with .values_list:
my_price = PriceListItem.objects.values_list_(
'price_{}'.format(settings.CURRENCY),
flat=True
).get(id=tarif_id)
This will only fetch that specific column from the database, which can be a (a bit) faster than first fetching the entire row into memory, and then discard all the rest later.
Here my_price is thus not a PriceListItem object, but the value that is stored for the specific price_cur column.
It will thus result in a query that looks like:
SELECT pricelistitem.price_cur
FROM pricelistitem
WHERE id=tarif_id

Parameter index indication without using a Set

Is there a way to index a parameter in Pyomo without creating a set,through the Param() function? Is it possible to do it via validate for example?
No. You need to create a Set object or use a built in container like a list. E.g.,
m.s = Set(initialize=[1,2,3])
m.p = Param(m.s)
or
m.p = Param([1,2,3])
If you do it the second way, then Pyomo will automatically create a Set object and add it to your model with the name p_index.

similar to .get() attribute for IndexedParam or IndexedVar

I need to check if a variable's index exist,while calling a Constraint initialization and if it does not exist i want to set the variable's value to 0.In a python dictionary you can do so with something like that: dict.get('not-a-key',0).Is there something similar for Pyomo objects?
We haven't added this method because one might expect to use it to return a new variable (that would not be owned by the container, because the get method does not modify a dictionary). Perhaps something like the setdefault method would make more sense here, but this is also not something that is currently built into the modeling interface.
One piece of functionality that you might be able to use is that Pyomo will implicitly construct a new variable object at a particular index if that index was added to the variable's indexing set after the initial declaration. Example:
model = ConcreteModel()
model.x_index = Set(initialize=[1])
model.x = Var(model.x_index)
model.x[1] # OK
model.x[2] # KeyError
model.x_index.add(2)
model.x[2] # OK (implicitly creates this object on the fly)

Is there a way to get each row's value from a database into an array?

Say I have a query like the one below. What would be the best way to put each value into an array if I don't know how many results there will be? Normally I would do this with a loop, but I have no idea how many results there are. Would I need run another query to count the results first?
<CFQUERY name="alllocations" DATASOURCE="#DS#">
SELECT locationID
FROM tblProjectLocations
WHERE projectID = '#ProjectName#'
</CFQUERY>
Depending on what you want to do with the array, you can just refer to the column directly for most array operations, eg:
i = arrayLen(alllocations["locationID"]);
Using that notation will work for most array operations.
Note that this doesn't "create an array", it's simply a matter that a query columns - a coldfusion.sql.QueryColumn object is close enough to a CFML array for CF to be able to convert it to one when an array is needed. Hence the column can be passed to an array function.
What one cannot do is this:
myArray = q["locationID"];
This is because by default CF will treat q["locationID"] as a string if it can, and the string value is what's in the first row of the locationID column in the q query. It's only when an array is actually required will CF convert it to an array instead. This is basically how loose-typing works.
So if you just need to pass your query column to some function that expects an array, you can use the syntax above. If you want to actually put the column into a variable, then you will need to do something like this:
myArray = listToArray(valueList(q.localtionID));
NB: make sure you use <cfqueryparam> on your filter values instead of hard-coding them into your SQL statement.
myquery.column.toArray() is also a good undocumented choice.
Since you're only retrieving 1 field value from the query, you could use ValueList() to convert the query results into a comma-delimited list of locationIds, then use listToArray() to change that list into an array.
If you were retrieving multiple field values from the query, then you'd want to loop through the query, copy all the field values from the given row into a struct, and then add that struct to an array using arrayAppend().
(If you're not familiar with these functions, you can look them up in the Adobe docs or on cfquickdocs.com).

Passing limited queryset to related_to() in django-tagging

I want to use the related_to() function in django-tagging and I am passing a queryset looking like this:
Chapter.objects.all().order_by('?')[:5] #the important thing here is the "[:5]"
My problem is that this function apparently uses the in_bunk() function and you Cannot use 'limit' or 'offset' with in_bulk
How can I restrict my queryset to only pass 5 objects and at the same time make use of in_bunk?
I know that related_to() lets you pass the variable num (which is the number of objects it should return) but I don't want it to output the same queryset every single time. So i came up with the idea of ordering it randomly and limiting it before it was passed to the function. But as you can see: limited querysets and bunk_it doesn't go hand in hand very well.
I found a solution though it wasn't the best and though it processes unnecessary data. I simply run through all instances of the model related to the current instance and I then sort randomly and slice afterwards:
related_objects = instance.related_to(Model) # all related objects are found
related_objects = random.sample(related_objects,5) # .. and afterwards sorted randomly and sliced