similar to .get() attribute for IndexedParam or IndexedVar - python-2.7

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)

Related

Changing parameter values inside a loup

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).

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.

Assigning object instances to ModelFields (and their magical journey to the database)?

I'm reading through the 'Creating a custom model field' and I'm having trouble undestanding the journey an object instance takes to the DB. It mentions:
It's important to realize that a Django field class is not what is stored in your model attributes. The model attributes contain normal Python objects. The field classes you define in a model are actually stored in the Meta class when the model class is created (the precise details of how this is done are unimportant here).
I understand that in writing a custom field, I am writing the glue code between a normal python object, and how it is saved to the database. It goes on to talk about get_prep_value and that:
The value parameter is the current value of the model's attribute (a field has no reference to its containing model, so it cannot retrieve the value itself)
As I understand, this is to say that value is the actual instance of whatever object you are trying to represent? i.e. (continuing the example) when I write:
myhand = Hand('Ah', '9s', '8c', '2d')
my_model.custom_hand_field = myhand
my get_prep_value method is called with myhand as the value?
If so, is a reference to myhand actually stored somewhere within the Field class, or is the field simply converting between the Hand and database value on the fly?
Furthermore, how does it get from the assignment of the hand to the model attribute in the code above to actually being stored in the DB via `get_prep_value' (whether or not a reference is stored in the Field class)?
tl;dr what magic is happening between an assignment of an instance to a model attribute and it reaching the DB, and how it get_prep_value involved?

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

Django - How to remove F() from a field?

after doing a query with F() (see http://docs.djangoproject.com/en/dev/topics/db/queries/#query-expressions), I save the object, but then, I need to save it again. I want to remove F() from the field. If I don't, F() gets called again.
For example
rank.ammountMatchesRanked = F('ammountMatchesRanked') + 1
rank.save() # does ammountMatchesRanked = ammountMatchesRanked + 1
... # Manipulating more rank fields (can't manipulate before)
rank.save() # does ammountMatchesRanked++ again (undesired)
Any idea on how can I clear reference fields? I have searched the documentation but I didn't find it.
Thanks in advance
Why are you using F() here at all? F is really for use within queries, where you want to just get those objects who have a certain property with some relation to another property in the same model. Once you've got the object, there's no need to use it - you can just do it in standard Python:
rank.ammountMatchesRanked += 1
rank.save()
Edited after comment No, you have misunderstood what lazy loading is. It applies to instances (ie database rows) within a queryset, not fields (ie columns) within an instance. So once you have accessed an instance at all, Django by default will load all its fields (except those you have marked with defer()), so the above will not result in an extra query.
The documentation for using F() in updates which you linked to explains that this is only if you're not doing anything else with the object. You are, so this is not an optimisation.
i am not that good in django, but what about doing this:
rank.ammountMatchesRanked = F('ammountMatchesRanked');
just before the second call?