create complicated domain for my attrs attribute - odoo

I want to build below logic for my attrs . Can some help me here ?
A OR B OR ( C OR ( (D AND E) OR (F AND G AND H) ) )
I tried with below logic
['|','|', (A), (B),'|'(C), '|','&', (D), (E),'&', (F),'&' (G),(H)]

It can be quite tricky to form such domains. In those cases you can use odoo.osv.expression helpers, which take a list of domains (not a list of leafs). Example:
>>> from odoo.osv.expression import AND, OR
>>> a,b,c,d,e,f,g,h = ([("field_" + x, "=", "value_" + x)] for x in "ABCDEFGH")
>>> OR([a, b, OR([c, AND([d, e]), AND([f, g, h])])])
['|', '|', ('field_A', '=', 'value_A'), ('field_B', '=', 'value_B'), '|', '|', ('field_C', '=', 'value_C'), '&', ('field_D', '=', 'value_D'), ('field_E', '=', 'value_E'), '&', '&', ('field_F', '=', 'value_F'), ('field_G', '=', 'value_G'), ('field_H', '=', 'value_H')]
Note: I had to convert your variables into valid domains or the methods wouldn't work.

Related

syntax in defining constraints in CVXPY

I am new to CVXPY, I learn by running examples and I found this post: How to construct a SOCP problem and solve using cvxpy and cvxpylayers #ben
The author provided the codes (Below I've corrected the line that caused an error in OP's EDIT 2):
import cvxpy as cp
import numpy as np
N = 5
Q_sqrt = cp.Parameter((N, N))
Q = cp.Parameter((N, N))
x = cp.Variable(N)
z = cp.Variable(N)
p = cp.Variable()
t = cp.Variable()
objective = cp.Minimize(p - t)
constraint_soc = [z == Q # x, x.value * z >= t ** 2, z >= 0, x >= 0] # <-- my question
constraint_other = [cp.quad_over_lin(Q_sqrt # x, p) <= N * p, cp.sum(x) == 1, p >= 0, t >= 0]
constraint_all = constraint_other + constraint_soc
matrix = np.random.random((N, N))
a_matrix = matrix.T # matrix
Q.value = a_matrix
Q_sqrt.value = np.sqrt(a_matrix)
prob = cp.Problem(objective, constraint_all)
prob.solve(verbose=True)
print("status:", prob.status)
print("optimal value", prob.value)
My question is here: x.value * z >= t ** 2
why only x.value while z not?
Actually I tried x * z, x.value * z.value, they both throw out errors, only the one in the original post works, which is x.value * z.
I googled and found this page and this, looks most relevant, but still failed to find an answer.
But both x and z are variables and defined as such
x = cp.Variable(N)
z = cp.Variable(N)
why only x needs a .value after?? Maybe it's a trivial question to experienced users, but I really don't get it. Thank you.
Update: two follow-up questions
Thanks to #MichalAdamaszek the first question above is clear: x.value didn't make sense here. A suggestion is using constraint_soc = [z == Q # x] + [ z[i]>=cp.quad_over_lin(t, x[i]) for i in range(N) ]
I have two following questions:
is it better to write the second of the soc constraint as : [ x[i]>=cp.quad_over_lin(t, z[i]) for i in range(N) ]? because in the question we only know that z[i] > 0 for sure. Or it doesn't matter at all in cvxpy? I tired both, both returned a similar optimal value.
I noticed that for the two constraints:
$x^TQx <= Np^2 $ and $ x_i z_i >= t^2 $
the quadratic terms were always intentionally split into two linear terms:
cp.quad_over_lin(Q_sqrt # x, p) <= N * p and z[i]>=cp.quad_over_lin(t, x[i]) respectively.
Is it because that in cvxpy, it is not allowed to have quadratic terms in (in)equality constraints? Is there an documentation to those basic rules?
Thank you.

Kohana combine orm factories

I have two factories "News" and "Photoset". Can I somehow combine them?
$news = ORM::factory('News')
->where('title_'.I18n::$lang, '<>', '')
->and_where('image', '<>', '')
->and_where('published', '=', 1)
->and_where('is_slider', '=', 1)
->and_where('date', '<', DB::expr('UNIX_TIMESTAMP()'))
->order_by('date','desc')
->limit(4)
->find_all();
$photoset = ORM::factory('Photoset')
->where('name_'.I18n::$lang, '<>', '')
->and_where('published', '=', 1)
->and_where('is_slider', '=', 0)
->order_by('date','desc')
->limit(4)
->find_all();
Okey, just converted them to array and merged.
$news = ORM::factory('News')
->where('title_'.I18n::$lang, '<>', '')
->and_where('image', '<>', '')
->and_where('published', '=', 1)
->and_where('is_slider', '=', 1)
->and_where('date', '<', DB::expr('UNIX_TIMESTAMP()'))
->order_by('date','desc')
->limit(4)
->find_all()
->as_array();
$photoset = ORM::factory('Photoset')
->where('name_'.I18n::$lang, '<>', '')
->and_where('published', '=', 1)
->and_where('is_slider', '=', 0)
->order_by('date','desc')
->limit(4)
->find_all()
->as_array();
$newArray = Arr::merge($news, $photoset);
What you want to do is the equivalent of UNION from SQL. ORMs aren't made for that...
The second thing is that mapping SQL results to objects in Kohana is slow. (But you don't seem to do that.) If you only need to display the results, it's better to use the query builder.
$q2 = DB::SELECT('id', DB::expr('set' AS 't'))->from('photoset')
->where('name_'.I18n::$lang, '<>', '')
->and_where('published', '=', 1)
->and_where('is_slider', '=', 0)
->order_by('date','desc')
->limit(4);
$q = DB::SELECT('id', DB::expr('news' AS 't'))->from('news')
->where('title_'.I18n::$lang, '<>', '')
->and_where('image', '<>', '')
->and_where('published', '=', 1)
->and_where('is_slider', '=', 1)
->and_where('date', '<', DB::expr('UNIX_TIMESTAMP()'))
->order_by('date','desc')
->limit(4)
->union($q2, TRUE);
$newArray = $q->execute()->as_array();

Julia-lang comparison of expression and commutativity

OK my title isn't great but it's easily explainable with an example.
julia>a = :(1 + 2)
julia>b = :(2 + 1)
julia>a == b
false
I have two expressions a and b. I would like to know if they will give me the same results without being evaluated.
I though that commutative operators like + or * could infer that the results would be the same.
EDIT:
Another way to understand it is to compare a very specific subset of expressions that can infer the commutativity of the function:
Expr(:call, +, a, b) <=> Expr(:call, +, b, a)
We can write a fairly simple function to check if two arrays have the same elements, modulo ordering:
function eq_modulo_ordering!(xs, ys) # note !, mutates xs and ys
while !isempty(xs)
i = findfirst(isequal(pop!(xs)), ys)
i === nothing && return false
deleteat!(ys, i)
end
isempty(ys)
end
eq_modulo_ordering(xs, ys) = eq_modulo_ordering!(copy(xs), copy(ys))
We can use then use this function to check if two top-level expressions are equivalent.
function expr_equiv(a::Expr, b::Expr, comm)
a.head === b.head || return false
a.head === :call || return a == b
a.args[1] ∈ comm || return a == b
eq_modulo_ordering(a.args, b.args)
end
expr_equiv(a, b, comm) = a == b
expr_equiv(a, b) = expr_equiv(a, b, [:+])
In the case that we want to check that two expressions are fully equivalent beyond the top-level, we could modify our functions to use mutual recursion to check if the subexpressions are expr_equiv, rather than isequal.
function eq_modulo_ordering!(xs, ys, comm) # note !, mutates xs and ys
while !isempty(xs)
x = pop!(xs)
i = findfirst(b -> expr_equiv(x, b, comm), ys)
i === nothing && return false
deleteat!(ys, i)
end
isempty(ys)
end
eq_modulo_ordering(xs, ys, comm) = eq_modulo_ordering!(copy(xs), copy(ys), comm)
function expr_equiv(a::Expr, b::Expr, comm)
a.head === b.head || return false
a.head === :call || return a == b
a.args[1] ∈ comm || return all(expr_equiv.(a.args, b.args, Ref(comm)))
eq_modulo_ordering(a.args, b.args, comm)
end
expr_equiv(a, b, comm) = a == b
expr_equiv(a, b) = expr_equiv(a, b, [:+])
We can now use expr_equiv as expected, optionally supplying a list of functions which are commutative.
julia> expr_equiv(:((a + b + b) * c), :((b + a + b) * c))
true
julia> expr_equiv(:((a + a + b) * c), :((b + a + b) * c))
false
julia> expr_equiv(:(c * (a + b + b)), :((b + a + b) * c), [:+, :*])
true
This is impossible. Figuring out whether two programs have the same result without evaluating them is called the Function Problem and is provably equivalent to solving the Halting Problem.
It is not possible to compute whether to pieces of code will have the same result.

Assignment to nested lists in Perl 6

I supposed, the result should be 1, 2, 3.
> my ($a, $b, $c)
> (($a, $b), $c) = ((1, 2), 3)
(((1 2) 3) (Any))
> $a, $b, $c
((1 2) 3 (Any))
What's wrong here?
There's nothing wrong (that is, ordinary assignment in P6 is designed to do as it has done) but at a guess you were hoping that making the structure on the two sides the same would result in $a getting 1, $b getting 2 and $c getting 3.
For that, you want "binding assignment" (aka just "binding"), not ordinary assignment:
my ($a, $b, $c);
:(($a, $b), $c) := ((1, 2), 3);
Note the colon before the list on the left, making it a signature literal, and the colon before the =, making it a binding operation.
If you want to have the result be 1, 2, 3, you must Slip the list:
my ($a, $b, $c) = |(1, 2), 3;
This is a consequence of the single argument rule: https://docs.raku.org/type/Signature#Single_Argument_Rule_Slurpy
This is also why this just works:
my ($a, $b, $c) = (1, 2, 3);
Even though (1,2,3) is a List with 3 elements, it will be auto-slipped because of the same single argument rule. You can of course also just remove the (superstitious) parentheses:
my ($a, $b, $c) = 1, 2, 3;
You are asking *What's wrong here", and I would say some variant of the single argument rule is at work. Since parentheses are only used here for grouping, what's going on is this assignment
($a, $b), $c = (1, 2), 3
(1, 2), 3 are behaving as a single argument, so they are slurpily assigned to the first element in your group, $a, $b. Thus they get it all, and por old $c only gets Any. Look at it this way:
my ($a, $b, $c);
($a, ($b, $c)) = ((1, 2), 3, 'þ');
say $a, $c; # OUTPUT: «(1 2)þ␤»
You might want to look at this code by Larry Wall, which uses »=«, which does exactly what you are looking for. It's not documented, so you might want to wait a bit until it is.

Django: Expression can be simplified. square brackets

def _by_list(request, names, every_name):
every_names = request.GET.getlist(every_name, '')
names_list = map(lambda n: Q(**{names:n}), every_names)
if names_list == []: # Expression can be simplified
return Q(**{names:'_'})
else:
return reduce(lambda a, b: a | b, names_list)
if i use 'if names_list' it's dosn't work as expected