First of all, thanks for helping me.
My question, lets say I have readme.txt file, and inside looks like below
a1 3
b2 4
c3 -2.3
d23 55.6
Now, how can I make a function to load this txt file, so that in the Octave, I will directly have
a1=3
b2=4
c3=-2.3
d23=55.6
Allow me say this again, DIRECTLY. Once I use this function "readFunction("readme.txt")", all those variables will be load, and ready to use.
I tried [name, num] = textread ("readme.txt", "%s %f"), "num" is the numbers, but I don't know how to convert the cell "name" to variable name. e.g it's wrong if I do char(name(1)) = b(1). (trying to do a1 = 3).
Or maybe my way is just completely wrong? Thanks for the help.
First, the idea:
Read line by line the file
Replace the space with and = symbol
Optionally add a ; symbol at the end of each line
eval the string.
Second, a simple code example:
filename="file.txt";
fid=fopen(filename);
line=fgetl(fid);
while line != -1
eval(strrep(line, ' ', '='));
line=fgetl(fid);
endwhile
fclose(fid);
Related
I am new to Octave and I've written the following function to combine sound pressure levels. I want to present the answer with a reference value after it. e.g.: 83 dB re: 20µPa rather than just 83, but I don't know how to add the text after the answer.
function L_total = combineLevels(Lp)
x = Lp./10;
y = 10.^x; z = sum(y);
L_total = 10*log10(z);
endfunction
Any advice would be appreciated. Thanks!
Sounds like you want to use fprintf or sprintf. These functions allow you to construct strings that interpolate values from variables. Try:
fprintf('%d dB re: %duPa\n', L_total, Lp);
Until now, I change req manually. The code works, including saving the result into a file.
But now I want to run the code for all possible values of req.
Without saving it into a file, the code works but obviously it overwrite the result.
That is why I put that line of code that saving the result by giving it a different name depending of the values of req. But this gives me error.
error:
error: sprintf: wrong type argument 'cell'
error: called from
testforloop at line 26 column 1
my code:
clear all;
clc;
for req = {"del_1", "del_2", "del_3"}
request = req;
if (strcmp(request, "del_1"))
tarr = 11;
# and a bunch of other variables
elseif (strcmp(request, "del_2"))
tarr = 22;
# and a bunch of other variables
elseif (strcmp(request, "del_3"))
tarr = 33;
# and a bunch of other variables
else
# do nothing
endif
#long calculation producing many variable including aa, bb, cc.
aa = 2 * tarr;
bb = 3 * tarr;
cc = 4 * tarr;
#collecting variables of interest: aa, bb, cc and save it to a file.
result_matrix = [aa bb cc];
dlmwrite (sprintf('file_result_%s.csv', request), result_matrix);
endfor
if I use ["del_1" "del_2" "del_3"], the error is
error: 'tarr' undefined near line 20 column 10
error: called from
testforloop at line 20 column 4
Inside the loop
for req = {"del_1", "del_2", "del_3"}
req gets as value each of the cells of the cell array, not the contents of the cells (weird design decision, IMO, but this is the way it works). Thus, req={"del_1"} in the first iteration. The string itself can then be obtained with req{1}. So all you need to change is:
request = req{1};
However, I would implement this differently, as so:
function myfunction(request, tarr)
% long calculation producing many variable including aa, bb, cc.
aa = 2 * tarr;
bb = 3 * tarr;
cc = 4 * tarr;
% collecting variables of interest: aa, bb, cc and save it to a file.
result_matrix = [aa bb cc];
dlmwrite (sprintf('file_result_%s.csv', request), result_matrix);
end
myfunction("del_1", 11)
myfunction("del_2", 22)
myfunction("del_3", 33)
I think this obtains a clearer view of what you're actually doing, the code is less complicated.
Note that in Octave, ["del_1" "del_2" "del_3"] evaluates to "del_1del_2del_3". That is, you concatenate the strings. In MATLAB this is not the case, but Octave doesn't know the string type, and uses " in the same way as ' to create char arrays.
I am writing a script to change the formatting of the text from one file, and create a new text file with the changes in formatting.
I have been able to remove unwanted characters, but haven't found a way to append text to the beginning of every line in the file.
Content from the original file looks like:
DMA 123 USA 12345
What I need it to look like after appending data to the start, middle, and end of the string:
<option label="DMA 123 USA" value="123"></option>
I have almost 100 lines that vary some, but follow the above formatting. I am trying to automate this as it will be a frequent task to adjust the original file to the new format for web publishing
I have been searching and haven't found any way to do it yet. Here is my current code:
path = 'file.txt'
tvfile = open(path,'r')
days = tvfile.read()
new_path = 'tvs.txt'
new_days = open(new_path,'w')
replace_me = ['-' ,'(' ,')' ,',' , '"' , ]
for item in replace_me:
days = days.replace(item,'')
days = days.strip()
new_days.write(days)
print(days)
tvfile.close()
new_days.close()
Nit: you need to prepend, not append. That said, try something along these lines:
buffer = ""
for item in replace_me:
line = "<option label=\""
line = line + days.replace(item,'').strip()
line = line + "\"></option>"
buffer = buffer + line
new_days.write(buffer)
I got a problem with running Octave function (ODE), I've tried already present solutions for this problem but nothing is working. I've also tried by saving my filename as egzamin.m but it too not worked.
Code from octave :
function dx=egzamin(x,t)
dx=zeros(4,1);
b=0;
g=9.81;
x1=x(1);
y1=x(2);
Vx=x(3);
Vy=x(4);
dx(1)=Vx;
dx(2)=Vy;
dx(3)=-b*Vx*sqrt(Vx.^2+Vy.^2);
dx(4)=-b*Vy*sqrt(Vx.^2+Vy.^2)-g;
endfunction
N=mod(291813,100);
x1=0;
y1=0;
Vx=20+N;
Vy=20+N;
t=0:0.01:500;
sol=lsode("egzamin",[x1,y1,Vx,Vy],t);
plot(sol(:,1),sol(:,2))
The error is :
error: 'x' undefined near line 5 column 4
error: called from
egzamin at line 5 column 3
Since the file starts with function, it is not a script file,
as explained in the doc:
Unlike a function file, a script file must not begin with the keyword
function
Add any statement (even dummy like 1;) before the function line to get a script file.
# dummy statement to get a script file instead of a function file
1;
function dx=egzamin(x,t)
g = 9.81;
Vx = x(3);
Vy = x(4);
dx = [Vx, Vy, 0, -g];
endfunction
N=mod(291813,100);
x1=0;
y1=0;
Vx=20+N;
Vy=20+N;
t=0:0.01:500;
sol=lsode("egzamin",[x1,y1,Vx,Vy],t);
plot(sol(:,1),sol(:,2))
A very clear explanation of what's going on is given here.
You need to save the function (thus from function to endfunction and naught else) as egzamin.m, and then execute the rest of the code in a script or at the command line. Alternatively, provided Octave does that the same as what MATLAB does nowadays, first put your script (N=(..) to plot()) and then the function.
This is necessary since you are defining your function first, so it doesn't have any inputs yet, as you don't define them until later. The function needs to have its inputs defined before it executes, hence you need to save your function separately.
You can of course save your "script" bit, thus everything which is currently below your function declaration, as a function as well, simply don't give it in- and outputs, or, set all the input parameters here as well. (Which I wouldn't do as it's the same as your
egzamin then.) e.g.
function []=MyFunc()
N=mod(291813,100);
x1=0;
y1=0;
Vx=20+N;
Vy=20+N;
t=0:0.01:500;
sol=lsode("egzamin",[x1,y1,Vx,Vy],t);
plot(sol(:,1),sol(:,2))
endfunction
I currently have a MATLAB function that looks like this:
function outfile=multi_read(modelfrom,modelto,type)
models=[modelfrom:1:modelto];
num_models=length(models);
model_path='../MODELS/GRADIENT/'
for id=1:num_models
fn=[model_path num2str(models(id)) '/']; %Location of file to be read
outfile=model_read(fn,type); %model_read is a separate function
end
end
The idea of this function is to execute another function model_read for a series of files, and output these files to the workspace (not to disk). Note that the output from model_read is a structure! I want the function to save the file to the workspace using sequential names, similar to typing:
file1=multi_read(1,1,x)
file2=multi_read(2,2,x)
file3=multi_read(3,3,x)
etc.
which would give file1, file2 and file3 in the workspace, but instead by recalling the command only once, something like:
multi_read(1,3,x)
which would give the same workspace output.
Essentially my questions is, how do I get a function to output variables with multiple names without having to recall the function multiple times.
As suggested in the comment I would try this approach which is more robust, at least IMHO:
N = tot_num_of_your_files; %whatever it is
file = cellfun(#(i)multi_read(i,i,x),mat2cell(1:N,1,ones(1,N)),...
'UniformOutput' , false); %(x needs to be defined)
You will recover objects by doing file{i}.
Here is code to do what you ask:
for i = 1:3
istr=num2str(i)
line = ['file' istr '= multi_read(' istr ', ' istr ', x)']
eval(line)
end
Alternatively, here is code to do what you should want:
for i = 1:3
file{i} = multi_read(i,i,x)
end