Optaplanner: Dynamically choose between hard/soft constraint? - dynamic

I know that you can insert a weight for each constraint dynamically, but is it possible to make the user be in charge of if a rule is adding points to hardConstraintMatch or softConstraintMatch?

Yes, its possible:
rule foo
when
MyParametrization($fooIsHard : fooIsHard)
... // actual pattern
then
if ($fooIsHard) {
scoreHolder.addHard...(...);
} else {
scoreHolder.addSoft...(...);
}
end

Related

sort the table by column name Exposed Kotlin

Good afternoon, I want to make a universal sort for all tables. The idea is that the method will receive the name of the column as input and, through reflection, I will receive a link to the field of the same name.
val id = "id"
var a = JobSeekerTable::class
a.memberProperties.forEach { e ->
if (e.name == id) {
transaction {
JobSeeker.all().sortedBy { e.getter }
}
}
}
Unfortunately, this does not work. There was an option, through the fields field that the table has
JobSeekerTable.fields.forEach {v->
transaction {
JobSeeker.all().sortedBy { v }
}
}
but also unsuccessfully :(
If there is any way to refer to the required field through the name. Not using if and stuff like that?
First, you are probably looking for orderBy, not sortedBy. The former is to order SQL query results, the later is to sort a collection.
Second, you want to pass an instance of a column:
val id = "id"
JobSeekerTable.selectAll().orderBy(JobSeekerTable.columns.find {
it.name == id // Here I used the name you provided, although probably it should be named something like columnName
} !! to SortOrder.ASC)
Using "screaming" operator (!!) in Kotlin is a bad practice. So if all of your tables have ID column, for example, you can use "elvis" operator instead.
JobSeekerTable.selectAll().orderBy((JobSeekerTable.columns.find {
it.name == id
} ?: JobSeekerTable.id) to SortOrder.ASC)

Check if a value is present in an (unsorted) array

In D language in operator allows to check if a value is present in a sorted random access range.
But if I want to check if a value is present in an unsorted and not random access range, how to do it?
While I agree with Lupus that countUntil does the job, there's a different function that may have less overhead and a more reasonable name: canFind:
import std.algorithm.searching : canFind;
if (haystack.canFind(needle)) {
// ...
}
Use std.algorithm.searching : countUntil
import std.algorithm.searching : countUntil
if (array.countUntil(lookingFor) != -1) {
// . . .
}
count Until is like indexOf in many other languages.
https://dlang.org/phobos/std_algorithm_searching.html#countUntil

In VTD-XML how to add new attribute into tag with existing attributes?

I'm using VTD-XML to update XML files. In this I am trying to get a flexible way of maintaining attributes on an element. So if my original element is:
<MyElement name="myName" existattr="orig" />
I'd like to be able to update it to this:
<MyElement name="myName" existattr="new" newattr="newValue" />
I'm using a Map to manage the attribute/value pairs in my code and when I update the XML I'm doing something like the following:
private XMLModifier xm = new XMLModifier();
xm.bind(vn);
for (String key : attr.keySet()) {
int i = vn.getAttrVal(key);
if (i!=-1) {
xm.updateToken(i, attr.get(key));
} else {
xm.insertAttribute(key+"='"+attr.get(key)+"'");
}
}
vn = xm.outputAndReparse();
This works for updating existing attributes, however when the attribute doesn't already exist, it hits the insert (insertAttribute) and I get "ModifyException"
com.ximpleware.ModifyException: There can be only one insert per offset
at com.ximpleware.XMLModifier.insertBytesAt(XMLModifier.java:341)
at com.ximpleware.XMLModifier.insertAttribute(XMLModifier.java:1833)
My guess is that as I'm not manipulating the offset directly this might be expected. However I can see no function to insert an an attribute at a position in the element (at end).
My suspicion is that I will need to do it at the "offset" level using something like xm.insertBytesAt(int offset, byte[] content) - as this is an area I have needed to get into yet is there a way to calculate the offset at which I can insert (just before the end of the tag)?
Of course I may be mis-using VTD in some way here - if there is a better way of achieving this then happy to be directed.
Thanks
That's an interesting limitation of the API I hadn't encountered yet. It would be great if vtd-xml-author could elaborate on technical details and why this limitation exists.
As a solution to your problem, a simple approach would be to accumulate your key-value pairs to be inserted as a String, and then to insert them in a single call after your for loop has terminated.
I've tested that this works as per your code:
private XMLModifier xm_ = new XMLModifier();
xm.bind(vn);
String insertedAttributes = "";
for (String key : attr.keySet()) {
int i = vn.getAttrVal(key);
if (i!=-1) {
xm.updateToken(i, attr.get(key));
} else {
// Store the key-values to be inserted as attributes
insertedAttributes += " " + key + "='" + attr.get(key) + "'";
}
}
if (!insertedAttributes.equals("")) {
// Insert attributes only once
xm.insertAttribute(insertedAttributes);
}
This will also work if you need to update the attributes of multiple elements, simply nest the above code in while(autoPilot.evalXPath() != -1) and be sure to set insertedAttributes = ""; at the end of each while loop.
Hope this helps.

How to query an index with a subcollection that has date ranges in RavenDB?

I prepared the full test case here: https://gist.github.com/pkrakowiak/cc8addf5725193a01f2d
There are Location documents. Each location can have zero or more sponsors during some time periods (represented by the IList<Sponsorship> Sponsors property). I need to return only those locations that are sponsored on a particular day (say 15th of March in my example). So such location must have at least one Sponsorship instance that matches the following query: .Where(x => x.Sponsors.Any(s => s.From <= today && s.To >= today))
I prepared two tests, one is not using an index explicitly: CanGetCurrentlySponsoredLocations, and one which uses a static index that I created: CanGetCurrentlySponsoredLocationsUsingStaticIndex. The first one will pass, the second one will fail. The question is - how do I make the second test pass? What sort of modifications do I need to apply to my Locations_ByCoordinates index?
In case you are wondering where the index name came from or what the reviews are - just ignore them. :) They are leftovers from other things that I was testing.
Update
I took this question first to the official RavenDB Google group: https://groups.google.com/forum/?fromgroups=#!topic/ravendb/ySUPXqkpTA8 Sadly, it did not bring me a solution.
The simplest index that will pass your unit test is:
private class Locations_ByCoordinates : AbstractIndexCreationTask<Location>
{
public Locations_ByCoordinates()
{
Map = locations => from l in locations
from s in l.Sponsors
select new
{
Sponsors_From = s.From,
Sponsors_To = s.To
};
}
}
You might want to pick a better name, since the coordinates aren't indexed.
I'm not sure what your other test CanSortOnSponsorshipStatus is all about though.
UPDATE
To include locations that have no sponsors, use the DefaultIfEmpty linq extension method. This will make sure that all locations have at least one index entry.
private class Locations_ByCoordinates : AbstractIndexCreationTask<Location>
{
public Locations_ByCoordinates()
{
Map = locations => from l in locations
from s in l.Sponsors
.DefaultIfEmpty(new Sponsorship
{
From = DateTime.MinValue,
To = DateTime.MaxValue
})
select new
{
Sponsors_From = s.From,
Sponsors_To = s.To
};
}
}

uniqueness of composite id with null component

I am running into problems using unique constraints.
The following combinations are allowed
A.name B.name
foo NULL
foo bar
foo bar1
foo1 bar
It should not be possible to create a new A with same name, only if it has a different B.
With the constraints below it is possible to create
A.name B.name
foo NULL
foo NULL
Because NULL seems not to have effect on unique.
Any hints how to fix this?
class A {
String name
static belongsTo = [b:B]
static constraints = {
name(unique:'b')
b(nullable:true)
}
}
class B {
String name
static hasMany = [as:A]
name(unique:true)
}
In the database structure, could you set the columns to NOT NULL DEFAULT 0 or similar, and then treat the zeros the same as you otherwise would the NULLs? Since the column is for names, there's likely to be no digits in the values anyway right?
I'm not entirely sure, but I think this will work:
name(unique:['b', 'name'])
Looking at the code for the unique constraint, it seems feasible. The constraint definitely lets you pass in a list of things to compare the uniqueness to. It calls this the uniquenessGroup. Then, when validating, it iterates over this list. Take a look starting at line 137 here: http://www.docjar.com/html/api/org/codehaus/groovy/grails/orm/hibernate/validation/UniqueConstraint.java.html
The code looks like this:
if(shouldValidate) {
Criteria criteria = session.createCriteria( constraintOwningClass )
.add( Restrictions.eq( constraintPropertyName, propertyValue ) );
if( uniquenessGroup != null ) {
for( Iterator it = uniquenessGroup.iterator(); it.hasNext(); ) {
String propertyName = (String) it.next();
criteria.add(Restrictions.eq( propertyName,
GrailsClassUtils.getPropertyOrStaticPropertyOrFieldValue(target, propertyName)));
}
}
return criteria.list();
}
So it depends on whether the GrailsClassUtils.getPropertyOrStaticPropertyOrFieldValue call will retrieve a property in the same class. Which based on the name it seems like it should.
I'm curious to know if it works for you.