matlab pathfinder - problems with understanding - matlab

I got an matlab-function which shall find files by returning their path. This is exactly what i need for my purpose. The problem is that the code is written by me. So I do not quite understand how this function works, especially the inputs which I do not understand.
I hope u can help me to understand this function.
Best regards!
Here is the code:
function B = getAllPaths(basepath, name)
temp=genpath(basepath);
A=regexp(temp,';','split');
j=1;
for i=1:length(A)-1
pfad=cell2mat(A(i));
if(exist([pfad name],'file'))
B(j)=cellstr(pfad);
j=j+1;
end
end
clear A i name pfad temp

I would write that function as
%// Get all child directories of 'basepath' that contain a file named 'name'
function B = getAllPaths(basepath, name)
A = regexp(genpath(basepath), ';', 'split');
B = A(cellfun(#(x) exist([x name],'file') ~= 0, A));
end
or
%// Get all child directories of 'basepath' that contain a file named 'name'
function B = getAllPaths(basepath, name)
if ispc
[OK,dirs] = system(['cd "' basepath '" && dir /s /b "' name '"']);
elseif isunix
[OK,dirs] = system(['find "' basepath '" -type f -name "' name '"']);
end
if ~OK
B = cellfun(#fileparts, cellstr(b), 'UniformOutput', false);
else
B = {};
end
end
MATLAB is interactive! So interact with it! Use any typical basepath and name and execute your function in the command window, line by line, displaying the output each time. Try to change a few commands and see how that changes the output. Type help cellfun and Read, Learn, Master. Click on links in see also [...] at the bottom of each help, even though you think you know it. Type edit cell2mat and Read, Learn, Master, etc. etc. etc.
Understanding a language takes practice, not a bunch of answers from some forum.

Thank you very much for your advice. I know it takes time to learn how to program. Im still examining this code but I have not understand it yet completely.
I got a problem with the line:
exist([pfad name],'file')
E.g. When I try to find "xyz" a file in folder "ABC" what must be in "name"? I write "ABC" in name but then it does net work.
Kind regards!

Related

Search and replace variable

I have some 100+ conf files that I am working. I need to find and replace various variable for all these files. For example, I'd like to find the line
Amplitude = 100; and replace it to: Amplitude = 200; for all files.
I've searched in online and found the solution only for one file. I'm looking for a way to do that in Matlab. Any ideas?
If these files can be opened as normal text files then I wouldn't use matlab. Notepad++ has an replace option for as many files as you want, just make sure, you test it out on a backup file first. so have it find "Amplitude = 100" and replace that by what you want.
To see how to do it, look here:
how-to-find-and-replace-lines-in-multiple-files
If you can't do that, put all the files in the same directory (you have to do this anyway). Then load the files in matlab with that directory and run a for loop. However it might be a bit slow./
Basically if you can do 1 file, you could do all of them with a for loop.
If you need help with that I show can some code I used before.
Well, Matlab solution would be to (recursively) open all files in the directory. Here I show example for non-recursive solution (it does not check subfolders), though it would be easy enough to modify it to search subfolders too if needed:
d = dir(yourPath);
for i = 1 : length(d)
if ~(d(i).isdir)
%d(i) is file.
replaceSingleFile(strcat(d(i).folder, d(i).name));
end
end
As you say, you already know how to do replace for a single file, though to have complete answer here, solution could be along the lines (in the function replaceSingleFile).
F = fopen(fileYouWantReplaced);
i = 1;
while (~feof(F))
L = fgetl(F);
L = strrep(L, 'Amplitude = 100;', 'Amplitude = 200;');
Buf{i} = L;
i = i + 1;
end
fclose(F);
%now just write all Buf to the same file again.
F = fopen(file..., 'w'); % Discard contents.
for i = 1 : numel(Buf)
fprintf(F, '%s\n', Buf{i});
end
fclose(F);

Matlab verification of file after copy

I would like to know whether we have a way using matlab to check the integrity of a file after copying to another folder.
I have 8 files in folder A. I will copy them in detination folder B. But at the end I want to verify that the copied files in folder B are exactly the same (size, integrity, data in the file) of the original file in folder A.
You could run a system command to compute a checksum & then parse it out from the captured output. It would depend on your OS which command would be appropriate.
The code below should get you started. I included examples for Windows and a little bit for Linux. However since I don't have my Linux Box turned on I didn't include any code to parse the cksum values from the system output.
if ispc
srcCmd = sprintf('CertUtil -hashfile %s MD5',fullPathToSourceFile);
dstCmd = sprintf('CertUtil -hashfile %s MD5',fullPathToDestFile);
[stat_S,cmdout_S] = system(srcCmd);
[stat_D,cmdout_D] = system(dstCmd);
parsed_S = textscan(cmdout_S,'%s','delimiter','\n');
MD5_S = parsed_S{1}{2};
parsed_D = textscan(cmdout_D,'%s','delimiter','\n');
MD5_D = parsed_D{1}{2};
if strcmp(MD5_S,MD5_D)
disp('MD5 Good :)')
else
disp('MD5 Bad :(')
end
elseif isunix
srcCmd = sprintf('cksum %s',fullPathToSourceFile);
dstCmd = sprintf('cksum %s',fullPathToDestFile);
[stat_S,cmdout_S] = system(srcCmd);
[stat_D,cmdout_D] = system(dstCmd);
%Insert parsing & checking code for Linux
end
Here is another way to check your files, it's kind of 'manually', we just open two files and check the data. MD5 check must be faster, but in my viewpoint, it would be changed accidentally when we view&save the file without changing.
clc; clear;
fA=dir('E:/folderA');
fB=dir('E:/folderB');
for i=1:length(fA)
pos=find(cellfun(#(x)isequal(x,fA(i).name),{fB.name}));
if (fA(i).isdir == 1 || isempty(pos))
continue;
end
%open file in FolderA
fid=fopen(['E:/folderA/' fA(i).name],'r');
dataA=fread(fid,inf,'char');
fclose(fid);
%open file in FolderB
fid=fopen(['E:/folderB/' fA(i).name],'r');
dataB=fread(fid,inf,'char');
fclose(fid);
%Isequal
if (isequal(dataA,dataB))
disp(['file ' fA(i).name ' is exactly the same.'])
else
%print something
end
end

Display TODO/FIXME report in Matlab's command window

Using the command
checkcode('function.m')
you can run the code analyzer on an m-file and output the report in the command window.
Is there any way to do this for TODO/FIXME reports? (without having to cd to the folder that contains the function and manually run it on the whole directory)
Bonus: If so, is it also possible to create custom tags? In eclipse, you can create custom TODO tags like "MTODO" and "JTODO" for different purposes/different people and have them displayed separately. Is this possible in Matlab?
Thanks in advance for any help! I will be continuing my google searches and will post the results if I find something.
You can use the internal function dofixrpt. This returns the HTML displayed in the report, rather than displaying the information at the command line, however.
% Run the report and show it
cd('myfolder')
dofixrpt;
% Alternatively, get the HTML of the report directly
html = dofixrpt;
% Write the HTML to a file
filename = tempname;
fid = fopen(filename, 'w');
fprintf(fid, '%s', html);
fclose(fid);
% View the HTML file
web(filename)
Type which dofixrpt or edit dofixrpt to see more details about what it does (it's basically a regular expression search for %.*TODO and %.*FIXME).
In the HTML report, you can find markers other than TODO and FIXME by specifying a custom marker (the default is NOTE). Unfortunately you can specify only one. If you're up to looking within dofixrpt and modifying it very slightly though, it would be very easy to make it look for more.
Finally you could also put in an enhancement request with MathWorks to provide a command similar to checkcode that will just do this for you and return the results at the command line. It seems like that would be very easy for them to do, and I'm surprised they haven't already done it, given that they've done something similar for helprpt, coveragerpt, deprpt etc.
Hope that helps!
I ended up writing my own code checker that calls checkcode on every m file in the specified folders.
fld_list = {pwd, 'folder', 'other_folder'};
nProblems = 0;
for iFld = 1:length(fld_list)
% fprintf('Checking %s...\n', fld_list{n});
files = dir(fullfile(fld_list{iFld}, '*.m'));
for f = 1:length(files)
filename = fullfile(fld_list{iFld}, files(f).name);
customCodeCheck(filename); %custom function
% check code analyzer
codeWarnings = checkcode(filename);
if not(isempty(codeWarnings))
fprintf('Problem found in %s\n', files(f).name);
for iData = 1:length(codeWarnings)
nProblems = nProblems + 1;
% print out link to problem
fprintf('line %d: %s\n', ...
filename, ...
codeWarnings(iData).line, codeWarnings(iData).line, ...
codeWarnings(iData).message);
end
end
end
end
You can add to this a customCodeCheck function that searches for TODO and FIXME and alerts you to their existence
function customCodeCheck(filename)
fileContents = fileread(filename);
toDos = strfind(fileContents, 'TODO');
fixMes = strfind(fileContents, 'FIXME');
% do other stuff
end

calling an external program in matlab in a loop

I have installed Matlab 2014 in Ubuntu. My problem:
I build several input files for another program, Quantum Espresso, in Matlab. Now I should pass these files to Quantum Espresso using matlab command line. Now I know I can do this using Linux Terminal, but my way of solving my problem has reached the point that my only option is 'calling Quantum Espresso from matlab'. One single call is actually easy:
! installation/folder/espresso-5.3.0/bin/pw.x < inputfile > outputfile
The problem is I have several input files named like 1name.in 1name.in ... . So this repeated calls should be done in a loop. But how?
I have tried:
the shell script for looping though the files. I added that extra '!' to each line of the script but it doesn't work.
I also tried to write a loop like this :
for i = 1:N
prefix = int2str(i);
fuloutname = [prefix 'name' '.' 'out'];
fulinname = [prefix 'name' '.' 'in'];
! adress/espresso-5.3.0/bin/pw.x < fulinname > fuloutname ;
end
In which 'N' in number of my input files. Clearly running this means you are passing a file nemaed 'fulinname' not 1name.in and will result in an output file named 'fuloutname'
I also tried to do it as you normally load various files in a loop but it also did not work
Please help me.
You should use the unix function:
for i = 1:N
prefix = int2str(i);
fuloutname = [prefix 'name' '.' 'out'];
fulinname = [prefix 'name' '.' 'in'];
mycommand = ['adress/espresso-5.3.0/bin/pw.x < ',fulinname,' > ',fuloutname];
unix(mycommand);
%system(mycommand); %will give you the same, result and this function is cross-platform
end

text scan iterations

I have some files to process , but i have missing files in middle
i am using
for i=1:file;
fid = fopen(['Raw',num2str(i),'.txt']);
D = textscan(fid1,'%*f %f%*f%*f%*f%f%f%[^\n]','delimiter',';', 'headerlines',50,'CollectOutput', 1);
fclose(fid);
Now the rest of program works well when i have files in order
i.e, 100,200 any number of files in my folder in order as Raw1.txt, Raw2.txt, Raw3.txt, ....
I get into trouble as soon as there are missing files like Raw1.txt, Raw4.txt, Raw5.txt
How do i iterate my text scan so it can ignore the file numbering?
Thanks
Edit :
By missing files i mostly mean numbers after 'Raw'
My files get generated as Raw1, Raw2, Raw3............ Raw400.txt
When all the files are in order and present i have no problem.
when i have some missing or jumps like for example
Raw1 . Raw2.......... Raw10, Raw15, Raw16
I have trouble as there is jump from Raw10.txt to Raw15.txt
I have same problem if my files start at anything other than Raw1.txt
look for exist in matlab documentation. Something like this should work:
for i=1:file;
if exist(['Raw',num2str(i),'.txt'], 'file')
% File exists!
fid = fopen(['Raw',num2str(i),'.txt']);
D = textscan(fid1,'%*f %f%*f%*f%*f%f%f%[^\n]','delimiter',';', 'headerlines',50,'CollectOutput', 1);
fclose(fid);
end
end
Note that exist(Name, 'file') checks for the file's directory too, so either give the full file name (i.e. with path), or try something like if exist(Name, 'file') == 2