class A(): pass
a = A()
setattr(a, 'dog', True)
Is there a MATLAB equivalent? If not, what's the most compact alternative? Currently I do
for i=1:length(keys)
k = keys{i};
v = values{i};
if k == "arg1"
obj.arg1 = v;
elseif k == "arg2"
obj.arg2 = v;
...
Likewise for getattr? If needed, assume all keys are already Properties.
Non-Python readers: setattr(obj, 'a', 1) <=> obj.a = 1 and getattr(obj, 'a') <=> obj.a.
obj.arg1 is the same as obj.('arg1').
So in your code snippet is equivalent to:
for i=1:length(keys)
obj.(keys{i}) = values{i};
end
Related
I have a Matlab function. I need to generalize this function. This code’s aim is to check this IndicMPs are in the TableTemp, if it is there, then we extract relevant age limits, such as: Age_Limite_DC, Age_Limite_IT, Age_Limite_Ch and Transfert_Prime_IT_DC. My idea is to generalize, passing parameters to find out the "Type_pret" is.(May be I'm wrong) Since I'm beginner to Matlab can someone help me to encode a more generic function that can be used in a more general context?
function Structure = optimisation_function()
Data = load('Data.mat');
Structure = Data.Structure;
TableTemp = Data.TableTemp;
Age_Limite_DC = zeros(size(Structure,1),1);
Age_Limite_IT = zeros(size(Structure,1),1);
Age_Limite_CH = zeros(size(Structure,1),1);
Transfert_Prime_IT_DC = zeros(size(Structure,1),1);
for IndexMPAL = 1 : length(Structure.AnneeSouscription)
% Determine Type_Pret (Loan Type)
if ~isempty(strfind(Structure.Type_Pret{IndexMPAL},'A'))
Type_Pret = 'A';
elseif ~isempty(strfind(Structure.Type_Pret{IndexMPAL},'B'))
Type_Pret = 'B';
elseif ~isempty(strfind(Structure.Type_Pret{IndexMPAL},'C'))
Type_Pret = 'C';
elseif ~isempty(strfind(Structure.Type_Pret{IndexMPAL},'D'))
Type_Pret = 'D';
elseif ~isempty(strfind(Structure.Type_Pret{IndexMPAL},'E'))
Type_Pret = 'E';
end
MP_CP = Structure.NomCodeProduit(IndexMPAL);
MP_AnSous = Structure.AnneeSouscription(IndexMPAL);
MP_TypePret = Type_Pret;
IndicCP = strcmp(MP_CP, TableTemp.CodeProduit);
IndicAS = MP_AnSous== TableTemp.AnneeSouscription;
IndicTP = strcmp(MP_TypePret, TableTemp.TypePret);
IndicMP = IndicCP & IndicAS & IndicTP;
if ~any(IndicMP)
Msg = strcat('CodeProduct:',MP_CP{1}, ', Année Souscription:', num2str(MP_AnSous), ', Type Prêt:', MP_TypePret);
error('Error', Msg)
else
Age_Limite_DC(IndexMPAL,1) = TableTemp.Age_Limite_DC(IndicMP,1);
Age_Limite_IT(IndexMPAL,1) = TableTemp.Age_Limite_IT(IndicMP,1);
Age_Limite_CH(IndexMPAL,1) = TableTemp.Age_Limite_CH(IndicMP,1);
Transfert_Prime_IT_DC(IndexMPAL,1)=
TableTemp.Transfert_Prime_IT_DC(IndicMP,1);
end
end
Structure.Age_Limite_DC = Age_Limite_DC;
Structure.Age_Limite_IT = Age_Limite_IT;
Structure.Age_Limite_CH = Age_Limite_CH;
Structure.Transfert_Prime_IT_DC = Transfert_Prime_IT_DC;
end
The if/elseif can be simplified with a cell array:
liststr = {'A','BB','C','D','E'}; % builds a cell array, each cell contains a string
Positive_matches = strfind(liststr,Structure.Type_Pret{IndexMPAL}) % returns a list for each cell of the indices where the element was found (empty if none)
Index = find(~cellfun('isempty', Positive_matches )) % converts the previous list into a logical 0/1 array indicating whether an item was found (1) or not (0)
% if isempty(Index); continue; end % If no index is found, to avoid an error in the next instruction, skips the rest of the code.
Type_Pret = liststr(Index(1));
If the Type_Pret are the same in your list and in Structure? , you can usestrcmp`:
liststr = {'A','B','C','D','E'};
if any(strcmp(Structure.Type_Pret,liststr))
Type_Pret = Structure.Type_Pret
else
% handle error
end
You can also work directly on Structure.Age_Limite_DC without using Age_Limite_DC.
I have n arrays or variable length
arr1 = [1,2,3]
arr2 = [1,3,5,8]
....
How can I compute the intersection of those n arrays ?
Consider checking out underscore.js library. It provides function for what you need and a bunch of other usefull functions.
Example from docs:
_.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]);
=> [1, 2]
Simple plain JS implementation can be found here. Same idea in CoffeeScript:
intersect_all = (lists) ->
if lists.length is 0
return []
else return lists[0] if lists.length is 1
partialInt = lists[0]
i = 1
while i < lists.length
partialInt = intersection(partialInt, lists[i])
i++
partialInt
The most efficient way is to use hashsets:
function hashset (elements) {
var i, set = {};
if (!Array.isArray(elements)) return elements;
for (i = 0; i < elements.length; i++) {
set[elements[i]] = true;
}
return set;
};
function intersect (a, b) {
var k
, s1 = hashset(a)
, s2 = hashset(b)
, s3 = {}
for (k in s1) {
if (s2[k]) s3[k] = true;
}
return s3;
};
Object.keys(intersect(arr1,arr2));
// ["1", "3"]
You will find CoffeeScript source of this code, benchmarks for it and some additional information in this question.
If you're going to to intersect huge arrays then I strongly recommend you to use this approach.
Either just use something like _.intersection or study the source of that implementation and rewrite it if you like.
Is something like this:
function [rv] = get_bla(m)
%#codegen
assert(isa(m,'char'));
assert(size(m, 1) >= 1);
assert(size(m, 1) <= 1024);
switch m
case 'xyz'
rv = 1;
case 'xyz1'
rv = 2;
otherwise
error('Unexpected something');
end
actually possible in the context of the matlab coder?
I am using:
codegen -config:dll get_bla
and get:
SWITCH expression has indeterminate size.
As 'char arrays' have to be of static size for C/C++, I presume the above is impossible or is there a work around?
Try using if-elseif statements instead of the switch statement.
if strcmp(m, 'xyz')
rv = 1;
elseif strcmp(m, 'xyz1')
rv = 2;
else
error('unexpected');
end
Is it somehow possible to concatenate two matlab structures recursively without iterating over all leaves of one of the structures.
For instance
x.a=1;
x.b.c=2;
y.b.d=3;
y.a = 4 ;
would result in the following
res = mergeStructs(x,y)
res.a=4
res.b.c=2
res.b.d=3
The following function works for your particular example. There will be things it doesn't consider, so let me know if there are other cases you want it to work for and I can update.
function res = mergeStructs(x,y)
if isstruct(x) && isstruct(y)
res = x;
names = fieldnames(y);
for fnum = 1:numel(names)
if isfield(x,names{fnum})
res.(names{fnum}) = mergeStructs(x.(names{fnum}),y.(names{fnum}));
else
res.(names{fnum}) = y.(names{fnum});
end
end
else
res = y;
end
Then res = mergeStructs(x,y); gives:
>> res.a
ans =
4
>> res.b
ans =
c: 2
d: 3
as you require.
EDIT: I added isstruct(x) && to the first line. The old version worked fine because isfield(x,n) returns 0 if ~isstruct(x), but the new version is slightly faster if y is a big struct and ~isstruct(x).
I need to merge two tables, with the contents of the second overwriting contents in the first if a given item is in both. I looked but the standard libraries don't seem to offer this. Where can I get such a function?
for k,v in pairs(second_table) do first_table[k] = v end
Here's what i came up with based on Doug Currie's answer:
function tableMerge(t1, t2)
for k,v in pairs(t2) do
if type(v) == "table" then
if type(t1[k] or false) == "table" then
tableMerge(t1[k] or {}, t2[k] or {})
else
t1[k] = v
end
else
t1[k] = v
end
end
return t1
end
Wouldn't this work properly?
function merge(t1, t2)
for k, v in pairs(t2) do
if (type(v) == "table") and (type(t1[k] or false) == "table") then
merge(t1[k], t2[k])
else
t1[k] = v
end
end
return t1
end
For numeric-index table merging:
for k,v in pairs(secondTable) do table.insert(firstTable, v) end
Doug Currie's answer is the simplest for most cases. If you need more robust merging of tables, consider using the merge() method from the Penlight library.
require 'pl'
pretty.dump(tablex.merge({a=1,b=2}, {c=3,d=4}, true))
-- {
-- a = 1,
-- d = 4,
-- c = 3,
-- b = 2
-- }
Here's iterative version for deep merge because I don't like potential stack overflows of recursive.
local merge_task = {}
function merge_to_left_o(orig, new)
merge_task[orig] = new
local left = orig
while left ~= nil do
local right = merge_task[left]
for new_key, new_val in pairs(right) do
local old_val = left[new_key]
if old_val == nil then
left[new_key] = new_val
else
local old_type = type(old_val)
local new_type = type(new_val)
if (old_type == "table" and new_type == "table") then
merge_task[old_val] = new_val
else
left[new_key] = new_val
end
end
end
merge_task[left] = nil
left = next(merge_task)
end
end
I preferred James version for its simplicity and use it in my utils.lua - i did add a check for table type for error handling.
function merge(a, b)
if type(a) == 'table' and type(b) == 'table' then
for k,v in pairs(b) do if type(v)=='table' and type(a[k] or false)=='table' then merge(a[k],v) else a[k]=v end end
end
return a
end
Thanks for this nice function which should be part of the table class so you could call a:merge(b) but doing table.merge = function(a, b) ... did not work for me. Could even be compressed to a one liner for the real nerds :)
Like Doug Currie said, you can use his function, but there is a problem with his method. If first_table has things in it's k index, the function will over write it.
I'm assuming you're trying to merge these tables, not overwrite index's and value's. So this would be my method, it's very similar but is used for merging tables.
for _, v in pairs(second_table) do table.insert(first_table, v) end
The only problem with this solution is that the index is set as numbers, not as strings. This will work with tables with numbers as the index, and for tables with strings as their index, use Doug Currie's method.
Doug Currie's method:
for k,v in pairs(second_table) do first_table[k] = v end
Extending this great answer, https://stackoverflow.com/a/1283399/1570165, I would like to go with a (pure) functional approach like this one below:
-- example values
local t1 = { a = 0, b = 2 }
local t2 = { a = 1, c = 3 }
-- merge function that takes functional approach
local merge = function(a, b)
local c = {}
for k,v in pairs(a) do c[k] = v end
for k,v in pairs(b) do c[k] = v end
return c
end
-- t1 and t2 value still same after merge
print(merge(t1, t2)) -- { a = 1, b = 2, c = 3 }
print(t2) -- { a = 1, c = 3 }
print(t1) -- { a = 0, b = 2 }
for k,v in pairs(t2) do t1[k] = v end
key for string solution