Picking subset of emums using Linq (for binding w/ ComboBox - wpf

I have an enum
public enum Positions : byte
{
Manager = 0,
CEO = 1,
Lawyer =2,
Intern =3,
Janitor = 4,
}
Is it possible to get a subset of these emums to bind with a ComboBox in WPF? Say only those enum values <=2 and >= 0? I was trying:
var subset = from p in Positions where p <= 2 && p >= 0 select p;
myComboBox.ItemsSource = subset;
without success (Positions is flagged as error with "Could not find an implementation of the query pattern...")
I was thinking that this would be nice to use LINQ on, but if there's another simple way, that would be interesting too.
Thanks,
Dave

You'll need to get the enum values and cast it to the proper type:
var subset = from p in Enum.GetValues(typeof(Positions)).Cast<int>()
where p <= 2 && p >= 0 select (Positions)p;

The last cast is unnecessary.
var subset = from p in Enum.GetValues(typeof(Positions)).Cast<Positions>() where p <= Postions.Lawyer && p >= Positions.Manager select p;

Related

Minizinc: counting number of different variables in array associated with initial output array

I'm trying to count occurrences within an array that are constrained by first having the same value in the array then by the number of different variables found an associated array.
I am starting with this model
set of int: OPTS = 1..4;
set of int: ASSIGN = 1..12;
array[ASSIGN] of var OPTS: result;
that can generate a result [ 1,2,1,3,3,4,1,3,1,1,2,4 ]
and would like to combine with these statements
enum CONDS = {A,B,C,D};
array[ASSIGN] of CONDS : const = [A,A,A,B,B,B,C,C,C,D,D,D];
array[OPTS] of var 0..max(CONDS): result2;
output ["\(result) \(result2)"]
and produce an output that counts how many different CONDS appear for each OPTS
[ 1,2,1,3,3,4,1,3,1,1,2,4 ] [3,2,2,2]
implying that OPTS[1] is associated with at least one of A,C and D, OPTS[2] has As and Ds, OPTS[3] has Bs and Cs, and OPTS[4] has Cs and Ds. I've scrambled my brains a bit with this and earlier questions and can't determine whether to look at creating a less complex constraint, or a more complex one. I could have missed a simple trick here...or maybe it's not so obvious?
I would love to know why my attempt with the following produces unsatisfiable when X = j, [0,0,3,0] when X = 1 and '[0,0,0,0]' when X = i (which would make east sense to me, but clearly I don't know how this position 'X' is supposed to work with the rest).
constraint forall(i in OPTS, j in CONDS)(
result2[i] =
count([ k == j /\ result[k] = i | k in const],X)
);
Here's a model that solves your original question. The construct card({const[i] | i in ASSIGN where result[i]=o} ), counts the number of different values of OPTS with the set comprehension {....}, using card (the cardinality of the set) to do the counting.
include "globals.mzn";
set of int: OPTS = 1..4;
set of int: ASSIGN = 1..12;
array[ASSIGN] of var OPTS: result = [1,2,1,3,3,4,1,3,1,1,2,4];
enum CONDS = {A,B,C,D};
array[ASSIGN] of CONDS : const = [A,A,A,B,B,B,C,C,C,D,D,D];
array[OPTS] of var 0..max(ASSIGN): result2;
solve satisfy;
constraint
forall(o in OPTS) (
% count the number of different CONDS for this OPTS value o
result2[o] = card({const[i] | i in ASSIGN where result[i]=o} )
)
;
output [
"result:\(result)\n",
"result2:\(result2)\n",
];
The solution is
result:[1, 2, 1, 3, 3, 4, 1, 3, 1, 1, 2, 4]
result2:[3, 2, 2, 2]
Update: Answer to the additional question
You asked why this constraint don't give the proper answer:
constraint forall(i in OPTS, j in CONDS)(
result2[i] =
count([ k == j /\ result[k] = i | k in const],X)
);
Here are some problems with this approach.
First I should say that this kind of loop might in general be a good approach, but the problem statement requires that we count the number of different chunks (were each chunk contains many values), not the number of all occurrences.
The k in const loops through all the values A,A,A,B,B,... (not the indices) which mean thatresult[k] is interpreted as result[A] ... result[D] which is then translated to as result[1] ... result[4] (A=1,B=2,C=3,D=4) which is not what you want.
Instead, k should loop though ASSIGN and instead of the plaink is should then be conds[k].
Another problem is that result2[i] is evaluated for every j in CONDS, i.e. it do "double counting" which almost always mean trouble. (Note also that in constraint programming values are never updated. If one got one value in results[i] in one loop and another value in another, then the model is UNSAT.)
Instead a nested loop should be used:
constraint
forall(i in OPTS) (
forall(j in CONDS) (
% ...
)
);
However, using count (or sum) means that you count all the
occurrences of the CONDS, e.g. for the value 1 this counts
two A's (from the first chunk) which is not correct.
To fix this one have to just count one occurrence of the CONDS. In the model above I use the set approach. Here's another way, using exists which just count one of each matching CONDS values.
constraint
forall(o in OPTS) (
result2[o] = sum(c in CONDS) (
exists(k in ASSIGN) ( const[k] = c /\ result[k] = o)
)
)
;

Propagating a selection on a subset of awkward-array back up

Is there a better way to do this logic? I want to propagate a selection from a lower-level selection available only on a subset of inner elements upwards
Specifically, I am looking to have an event level cut for oppositely charged muon-electron pair.
req_mu = (events.Muon.counts >= 1)
req_ele = (events.Electron.counts >= 1)
req = req_ele & req_mu
def propagate_up(subset, selection):
'''
subset: bool array slice on upper level
'''
dummy = np.zeros_like(subset)
dummy[subset] = selection
return dummy
req_opposite_charge = propagate_up(req, events[req].Muon[:, 0].charge * events[req].Electron[:, 0].charge == -1)
The easiest way to select a pair from separate collections is with cross, e.g.
good_el = electrons[electrons.pt > 10]
good_mu = muons[muons.pt > 10]
pairs = good_el.cross(good_mu)
# filter our pairs to have opposite charge (jagged mask)
pairs = pairs[pairs.i0.charge == -1 * pairs.i1.charge]
# filter events to have exactly one good pair
pairs = pairs[pairs.counts == 1]
# get the two leptons as a now flat array
el, mu = pairs.i0[:, 0], pairs.i1[:, 0]

Finding molar mass with MATLAB

Alrighty, so I have a pretty 'simple' problem on my hands. I am given two inputs for my function: a string that gives the formula of the equation and a structure that contains the information I need and looks like this:
Name
Symbol
AtomicNumber
AtomicWeight
To find the molecular weight, I have to take all of the elements in the formula, find their total mass and add them all together. For example, let's say that I have to find the molecular weight of oxygen. The formula would look like:
H2,O
The molecular weight will thus be
2*(Hydrogen's weight) + (Oxygen's weight), which evaluates to 18.015.
There will always be a comma separating the different elements in a formula. What I am having trouble with right now, is taking the number out of the string(the formula). I feel like I'm over-complicating how I am going about extracting it. If there's a number, I know it can be in positions 2 or 3 (depending on the element name). I tried to use isnumeric, I tried to do some really weird, coding stuff (which you'll see below), but I am having difficulties.
test case:
mass5 = molarMass('C,H2,Br,C,H2,Br', table)
mass5 => 187.862
table:
Name Symbol AtomicNumber AtomicWeight
'Carbon' 'C' 6 12.0110000000000
'Hydrogen' 'H' 1 1.00800000000000
'Nitrogen' 'N' 7 14.0070000000000
'Oxygen' 'O' 8 15.9990000000000
'Phosphorus''P' 15 30.9737619980000
'Sulfur' 'S' 16 32.0600000000000
'Chlorine' 'Cl' 17 35.4500000000000
'Bromine' 'Br' 35 79.9040000000000
'Sodium' 'Na' 11 22.9897692800000
'Magnesium' 'Mg' 12 24.3050000000000
My code so far is:
function[molar_mass] = molarMass(formula, information)
Names = []; %// Creates a Name array
[~,c] = size(information); %Finds the rows and columns of the table
for i = 1:c %Reads through the columns
Molecules = getfield(information(:,i), 'Name'); %Finds the numbers in the 'Name' area
Names = [Names {Molecules}];
end
Symbols = [];
[~, c2] = size(information);
for i = 1:c2 %Reads through the columns
Symbs = getfield(information(:,i), 'Symbol'); %Finds the numbers in the 'Symbol'
Symbols = [Symbols {Symbs}];
end
AN = [];
[~, c3] = size(information);
for i = 1:c3 %Reads through the columns
Atom = getfield(information(:,i), 'AtomicNumber'); %Finds the numbers in the 'AtomicWeight' area
AN = [AN {Atom}];
end
Wt = [information(:).AtomicWeight];
formula_parts = strsplit(formula, ','); % cell array of strings
total_mass = 0;
multi = [];
atoms = [];
Indices = [];
for ipart = 1:length(formula_parts)
part = formula_parts{ipart}; % Takes in the string
isdigit = (part >= '0') & (part <= '9'); % A boolean array
atom = part(~isdigit); % Select all chars that are not digits
Indixes = find(strcmp(Symbols, atom));
Indices = [Indices {Indixes}];
mole = atom;
atoms = [atoms {mole}];
natoms = part(isdigit); % Select all chars that are digits
% Convert natoms string to numbers, default to 1 if missing
if length(natoms) == 0
natoms = '1';
multi = [multi {natoms}];
else
natoms = num2str(natoms);
multi = [multi {natoms}];
end
end
multi = char(multi);
multi = str2num(multi); %Creates a number array with my multipliers
f=56;
Molecule_Wt = Wt{Indices};
duck = 62;
total_mass = total_mass + atom_weight * multi;
end
Thanks to Bas Swinckels I can now extract the numbers from the formulas, but what I'm struggling with now is how to pull out the weights associated with the symbols. I created my own weight_chart, but strcmp won't work there. Neither will strfind or strmatch. What I want to do is find the formulas in my input, in the chart. Then index it from that index, to the column (so add 1 I believe). How do I find the indices though? I'd prefer to find them in the order the strings appear in my input, since I can then apply my 'multi' array to it.
Any help/suggestions would be appreciated :)
Given the string, you can pull out the part that is a digit character with the isstrprop function. Then use that to address your string to get just those characters, then cast that as a double with str2double.
PartialString = 'H12';
Subscript = str2double (PartialString (isstrprop (PartialString, 'digit')));
This should get you started, there is still some parts that need to be filled in:
formula_parts = strsplit(formula, ','); % cell array of strings
total_mass = 0;
for ipart = 1:length(formula_parts)
part = formula_parts{ipart}; % string like 'H2'
isdigit = isstrprop(part, 'digit'); % boolean array
atom = part(~isdigit); % select all chars that are not digits
natoms = part(isdigit); % select all chars that are digits
% convert natoms string to int, default to 1 if missing
if length(natoms) == 0
natoms = 1;
else
natoms = num2str(natoms);
end
% calculate weight
atom_weight = lookup_weight(atom); % somehow look up value in table
total_mass = total_mass + atom_weight * natoms;
end
See this old question about how to extract letters or digits from a string.

Array index syntax in R

I am going over HoltWinters algorithm source code and having tough time understanding following syntax.
len value is 20, shouldn't level[-len-1] result level[-21] which will be not a valid index, isn't it? But somehow R treating it as level[20]. I couldn't find any documentation in R about this syntax.
Here is part of source I am referring:
fitted <- ts(cbind(xhat = final.fit$level[-len-1],
level = final.fit$level[-len-1],
trend = if (!is.logical(beta) || beta)
final.fit$trend[-len-1],
season = if (!is.logical(gamma) || gamma)
final.fit$seasonal[1L:len]),
start = start(lag(x, k = 1 - start.time)),
frequency = frequency(x)
)
A subscript -n for an R vector (with n > 0) means that element n is excluded.

Selecting Consecutive Entries with LINQ to Entities

I have a database table with rows that each contain a sequential index. I want to select groups of rows that are consecutive based upon this index column. For example, if I had rows with the following index values:
1
3
4
5
7
9
10
11
12
15
16
and I wanted to select all groups with 3 consecutive indices (this number will vary). I would get the following groups:
3, 4, 5
9, 10, 11
10, 11, 12
Basically, I'm trying to achieve something similar to the question posed here:
selecting consecutive numbers using SQL query
However, I want to implement this with LINQ to Entities, not actual SQL. I would also prefer not to use stored procedures, and I don't want to do any sort of ToList/looping approach.
Edit: Groups with more than the requested consecutive elements don't necessarily need to be split apart. i.e. in the previous example, a result of 9, 10, 11, 12 would also be acceptable.
So I think I've come up with a pretty good solution modeled after Brian's answer in the topic I linked to.
var q = from a in query
from b in query
where a.Index < b.Index
&& b.Index < a.Index + 3
group b by new { a.Index }
into myGroup
where myGroup.Count() + 1 == 3
select myGroup.Key.Index;
Change 3 to the number of consecutive rows you want. This gives you the first index of every group of consecutive rows. Applied to the original example I provided, you would get:
3
9
10
I think this might work pretty efficiently (C# though):
int[] query = { 1, 3, 4, 5, 7, 9, 10, 11, 12, 15, 16 };
int count = 3;
List<List<int>> numbers = query
.Where(p => query.Where(q => q >= p && q < p + count).Count() == count)
.Select(p => Enumerable.Range(p, count).ToList())
.ToList();
using (var model = new AlbinTestEntities())
{
var triples = from t1 in model.Numbers
from t2 in model.Numbers
from t3 in model.Numbers
where t1.Number + 1 == t2.Number
where t2.Number + 1 == t3.Number
select new
{
t1 = t1.Number,
t2 = t2.Number,
t3 = t3.Number,
};
foreach (var res in triples)
{
Console.WriteLine(res.t1 + ", " + res.t2 + ", " + res.t3);
}
}
It generates the following SQL
SELECT
[Extent1].[Number] AS [Number],
[Extent2].[Number] AS [Number1],
[Extent3].[Number] AS [Number2]
FROM [dbo].[Numbers] AS [Extent1]
CROSS JOIN [dbo].[Numbers] AS [Extent2]
CROSS JOIN [dbo].[Numbers] AS [Extent3]
WHERE (([Extent1].[Number] + 1) = [Extent2].[Number]) AND (([Extent2].[Number] + 1) = [Extent3].[Number])
It might be even better to use an inner join like this
using (var model = new AlbinTestEntities())
{
var triples = from t1 in model.Numbers
join t2 in model.Numbers on t1.Number + 1 equals t2.Number
join t3 in model.Numbers on t2.Number + 1 equals t3.Number
select new
{
t1 = t1.Number,
t2 = t2.Number,
t3 = t3.Number,
};
foreach (var res in triples)
{
Console.WriteLine(res.t1 + ", " + res.t2 + ", " + res.t3);
}
}
but when I compare the resulting queries in management studio they generate the same execution plan and take exactly the same time to execute. I have only this limited dataset you might compare the performance on your dataset if it is larger and pick the best if they differ.
The following code will find every "root".
var query = this.commercialRepository.GetQuery();
var count = 2;
for (int i = 0; i < count; i++)
{
query = query.Join(query, outer => outer.Index + 1, inner => inner.Index, (outer, inner) => outer);
}
var dummy = query.ToList();
It will only find the first item in each group so you will either have to modify the query to remeber the other ones or you could make a query based on the fact that you have the roots and from those you know which indexes to get. I'm sorry I couldn't wrap it up before I had to go but maybe it helps a bit.
PS. if count is 2 as in this case it means if finds groups of 3.

Resources