Save variables to file at runtime - metaprogramming

I'm looking for some functionality in Julia comparable to Matlab's
save('myfile.mat', 'myvar1', 'myvar2')
For example, using HDF5.jl, it is easy to do
#write filename myvar1 myvar2
But this requires that I know exactly which variables I want to write to the file.
I'd like to be able to choose which variables to write at run time, in a function scope, and specify their names using symbols or strings.
vars = [:myvar1, :myvar2]
#write filename vars
What would be the best way to accomplish this?
EDIT
I know that I can use save from JLD.jl as save("file.jld", "myvar1", myvar1). But I want to be able to save a list of variables that are not known at compile time, allowing a single call to save (or similar):
if condition
myvar1 = 1
vars = [:myvar1]
else
myvar1 = 1
myvar2 = 2
vars = [:myvar1, :myvar2]
end
# what goes here?
save(filename, vars...)

You may want to take a look at the JLD package, which builds on HDF5 with better support of user-defined Julia types. Both HDF5 and JLD provide functions for save that take run-time names for variables.

You can use serialize and deserialize:
vars = Dict()
if condition
myvar = 1
vars[:myvar1] = myvar1
else
myvar1 = 1
myvar2 = 2
vars[:myvar1] = myvar1
vars[:myvar2] = myvar2
end
f = open( filename, "w" )
serialize( f, vars )
close( f )
to read:
f = open( filename, "r" )
vars = deserialize( f )
close( f )
if you don't need to save variable names you can use array instead of dict: vars = []

Related

Expanding anonymous function into a string

I have a set of anonymous functions, and I want to convert them into strings. Normally I would just use func2str, but the problem is I want the variables and internal functions to be expanded out into their "true" values. The problem I'm running into is that MATLAB is keeping these by the names, but recognizing the values. Example
classdef Bclass
properties
equation
end
function obj = Bclass(inEquation, inValue)
obj.equation = #(t,y) inEquation(t,y) * inValue;
end
function out = getStr(obj)
out = func2str(obj.equation);
end
end
The problem is that the func2str call is outputting #(t,y) inEquation(t,y) * inValue, when I actually want it to output something like #(t,y) t*y * 5, if we had said b = Bclass(#(t,y) t*y, 5).
Is there a way to retrieve these variable values from MATLAB?
You can do this, but it could quickly become very difficult if your problem becomes any more complex than the example given above (i.e. more complicated anonymous functions, multiple nesting levels, etc.). You'll have to make use of the functions function to get information on the function handle, and its behavior may change between releases. Additionally, you'll have to do quite a bit of string manipulation (using functions like regexp, regexprep, strsplit, and strrep, as I do below).
I've tried to include here the most general approach I could, allowing for the following possibilities:
inEquation can be a non-anonymous function handle (i.e. #times).
inEquation can simply be passed along as is without actually being invoked.
inEquation can be called multiple times in the anonymous function.
The input arguments to inEquation can be named differently than what it is invoked with in obj.equation.
obj.equation can contain indexing operations.
First, we'll initialize some variables to mimic your example:
f1 = #(m, n) m*n; % Note the different variable names, but it will still work
inEquation = f1;
inValue = 5;
f2 = #(t, y) inEquation(t, y)*inValue; % Function constructed using workspace variables
Next, we'll get the function information for f2:
s = functions(f2);
varNames = fieldnames(s.workspace{1});
varValues = struct2cell(s.workspace{1});
out = s.function;
The workspace field holds the variable names and values that were used to construct f2, and the function field is the string you'd get by calling func2str on f2. We'll also need to compute a few things so we can correctly parse opening and closing parentheses in f2:
openIndex = (out == '(');
closeIndex = (out == ')');
parenIndex = cumsum(openIndex-[false closeIndex(1:end-1)]).*(openIndex | closeIndex);
Now, we'll loop over the workspace variables, convert their values to strings (if possible), and replace them in out:
for iVar = 1:numel(varNames)
name = varNames{iVar};
value = varValues{iVar};
if isa(value, 'function_handle') % Workspace variable is a function handle
value = func2str(value);
callIndex = strfind(out, [name, '('])+numel(name);
fcnParts = regexp(value, '#\({1}([^\)])*\){1}(\S)*', 'once', 'tokens');
if isempty(callIndex) % Function handle is not invoked
if isempty(fcnParts) % Non-anonymous function handle (i.e. #times)
value = ['#' value];
end
out = strrep(out, name, value);
elseif isempty(fcnParts) % Invoked function handle (i.e. #times)
out = strrep(out, name, value);
else % Invoked anonymous function handle
for iCall = callIndex
args = out(iCall+(1:find(parenIndex(iCall+1:end) == parenIndex(iCall), 1)-1));
value = regexprep(fcnParts{2}, ...
strcat('(?<!\w)', strsplit(fcnParts{1}, ','), '(?!\w)'), ...
strsplit(args, ','));
out = strrep(out, [name, '(', args, ')'], value);
end
end
elseif isnumeric(value) && isscalar(value) % Workspace variable is a numeric scalar
out = strrep(out, name, num2str(value));
end
end
And we get the desired result for out:
>> out
out =
#(t,y)t*y*5
Note that this will also work as expected with a non-anonymous function handle as well:
>> f1 = #times;
>> inEquation = f1;
>> inValue = 5;
>> f2 = #(t, y) inEquation(t, y)*inValue;
% Repeat above processing...
>> out
out =
#(t,y)times(t,y)*5
It will also work on some more complicated functions:
>> postVolt = #(g, V) -.05*g*(V+80);
>> preIdx = 5;
>> postIdx = 1;
>> index = 6;
>> obj.values = {};
>> f2 = #(t) postVolt(obj.values{preIdx}(index), obj.values{preIdx}(obj.voltIdx{postIdx}));
% Repeat above processing...
>> out
out =
#(t)-.05*obj.values{5}(6)*(obj.values{5}(obj.voltIdx{1})+80)

Python3 - Dynamically calling variables in a loop and writing into file

I have some of variables I would like to write in a file. Since they are pretty much well ordered (01,12 etc) I want to put them inside a loop.
For that, one needs to convert the variable result into a string. The problem is that if I do that, I'll write the very same string that is my variable name (and not my variable result, converted to string).
r01=func_dif(t0g,t1g)
r23=func_dif(t2g,t3g)
r34=func_dif(t3g,t4g)
r45=func_dif(t4g,t5g)
r56=func_dif(t5g,t6g)
r67=func_dif(t6g,t7g)
a = 0
b = 1
with open('script2Out', 'w') as f:
for a in range(7):
f.write('r{}{} = {} \n'.format(a,b,str(f'r{a}{b}')))
a += 1
b += 1
As you have probably guessed, here is what I get
r01 = r01
r12 = r12
r23 = r23
r34 = r34
r45 = r45
r56 = r56
r67 = r67
Whereas I wish to get something like (my variable results are lists)
r01 = [5.24,21,74,95,66]
...
You can do this using python's eval() function:
a = 0
b = 1
with open('script2Out', 'w') as f:
for a in range(7):
f.write('r{}{} = {} \n'.format(a,b,str(eval('r{a}{b}'))))
b += 1

matlab AND excel AND indexing

I have four files, each which I have to extract two columns.
Data21 = xlsread('Data21','Hits'); %% the files are names Data21/22/23/24
Hits = Data21(:,[4,15])
Data21 = xlsread('Data21','FA');
FA = Data21(:,[4,15]);
FA(FA == 4) = 0 ;
Cond21 = [FA,Hits]
I can't seem to use a count to get this to work on a loop. Does anyone have suggestions?
Thank you in advance
I'll go on the assumption you want to loop files and don't know how to create a loop that generates filenames.
You can create such an iteration over filenames using sprintf, e.g.:
for i = [21 : 24]
filename = sprintf ('Data%d', i);
Data = xlsread (filename, 'Hits');
% ... etc, etc.
end

how to extracted updated string after calling string.gsub in lua?

Problem Description:
HI there. I'm trying to figure out how to use the lua function "string.gsub". I've been reading the manual which says:
This is a very powerful function and can be used in multiple ways.
Used simply it can replace all instances of the pattern provided with
the replacement. A pair of values is returned, the modified string and
the number of substitutions made. The optional fourth argument n can
be used to limit the number of substitutions made:
> = string.gsub("Hello banana", "banana", "Lua user")
Hello Lua user 1
> = string.gsub("banana", "a", "A", 2) -- limit substitutions made to 2
bAnAna 2
Question
When it says that a pair of values is returned; how do I get the new string value?
Code
local email_filename = "/var/log/test.txt"
local email_contents_file_exists = function(filename)
file = io.open(filename, "r")
if file == nil then
return false
else
file.close(file)
return true
end
end
local read_email_contents_file = function()
print('inside the function')
if not email_contents_file_exists(email_filename) then
return false
end
local f = io.open(email_filename, "rb")
local content = f:read("*all")
f:close()
print(content)
--content = string.gsub(content, '[username]', 'myusername')
--local tmp {}
--tmp = string.gsub(content, '[username]', 'myusername')
print(string.gsub(content, '[username]', 'myusername'))
return content
end
local test = read_email_contents_file()
What I've Tried So Far:
I've tried just printing the results, as you see above. That returns a bunch of garbled text. Tried saving to original string and I've also tried saving the results to an array (local tmp = {})
Any suggestions?
> = string.gsub('banana', 'a', 'A', 2)
bAnAna 2
> = (string.gsub('banana', 'a', 'A', 2))
bAnAna
You were going pretty good with reading the Lua users wiki.
In Lua, when you a function returns more than one value, you can access them all as follows
function sth()
return 1, "hi", false
end
x, y, z, a, b, c = sth() -- x = 1; y = "hi" and z = false(boolean); a = b = c = nil
Now, coming back to string.gsub function. It returns two values. The first being the processed string and the second being the number of time gsub performed itself on the input string.
So, to get the new string value, something like this would be best:
local tempString = string.gsub(content, '[username]', 'myusername')
OR
local tempString = content:gsub( '[username]', 'myusername' )
Ofcourse, here, you need to be aware about the various patterns used in Lua which are mentioned in the Programming in Lua book.
You need to escape [ and ] because they are magic characters in Lua patterns.

MATLAB generate combination from a string

I've a string like this "FBECGHD" and i need to use MATLAB and generate all the required possible permutations? In there a specific MATLAB function that does this task or should I define a custom MATLAB function that perform this task?
Use the perms function. A string in matlab is a list of characters, so it will permute them:
A = 'FBECGHD';
perms(A)
You can also store the output (e.g. P = perms(A)), and, if A is an N-character string, P is a N!-by-N array, where each row corresponds to a permutation.
If you are interested in unique permutations, you can use:
unique(perms(A), 'rows')
to remove duplicates (otherwise something like 'ABB' would give 6 results, instead of the 3 that you might expect).
As Richante answered, P = perms(A) is very handy for this. You may also notice that P is of type char and it's not convenient to subset/select individual permutation. Below worked for me:
str = 'FBECGHD';
A = perms(str);
B = cellstr(reshape(A,7,[])');
C = unique(B);
It also appears that unique(A, 'rows') is not removing duplicate values:
>> A=[11, 11];
>> unique(A, 'rows')
ans =
11 11
However, unique(A) would:
>> unique(A)
ans =
11
I am not a matlab pro by any means and I didn't investigate this exhaustively but at least in some cases it appears that reshape is not what you want. Notice that below gives 999 and 191 as permutations of 199 which isn't true. The reshape function as written appears to operate "column-wise" on A:
>> str = '199';
A = perms(str);
B = cellstr(reshape(A,3,[])');
C = unique(B);
>> C
C =
'191'
'199'
'911'
'919'
'999'
Below does not produce 999 or 191:
B = {};
index = 1;
while true
try
substring = A(index,:);
B{index}=substring;
index = index + 1;
catch
break
end
end
C = unique(B)
C =
'199' '919' '991'

Resources