This is not exactly a question, because i have the answer, but as I couldn't find sources about it, i'll post the question along with the answer here in case it is of some interest for you. (And also to be able to find it again if i forget about how i did it).
I came across a problem while reviewing some code. The huge amount of variables were not explained in the code and everytime I wanted to know the meaning of a variable I had to look in the Data files and/or guess their meaning from the operations that were done in the code.
No need to say that this was pretty time consuming and i've searched the best way to lose less time.
First of all, I put all the explanations about the variables in comments, the problem being it's adding a (huge!) lot of lines in the script.
I'm also using the "Enable data tips in edit mode" in MATLAB. When you hover over a variable name MATLAB already evaluated, it gives you it's size along all dimensions and at least its first values, making it already easier to know what objects you are manipulating. (see image below)
The natural idea that came to my mind was the following : would it be possible to make MATLAB display some more custom informations in the data tips?
And the answer is yes!
See code in answer
We will need to do some preprocessing in order for this to work, i.e. :
1) Create a data file linking the variable names to their description (This is the boring part, although i already had to do it in order to understand the code. Just add a line everytime you come across a new variable)
I chose to save these datas in a CSV file, where the first column contains the variable names and the second one contains the descriptions, e.g.
2) Edit MATLAB's function datatipinfo
(It's inner code can be accessed by typing edit datatipinfo
in MATLAB's command window)
The datatipinfo
function looks like :
function datatipinfo(val)
% Some error checking / Initialization
function prefix=sizeType %#ok<DEFNU> All uses are in EVALC calls.
s = size(val);
D = numel(s);
if D == 2
theSize = [num2str(s(1)), 'x', num2str(s(2))];
elseif D == 3
theSize = [num2str(s(1)), 'x', num2str(s(2)), 'x', ...
num2str(s(3))];
else
theSize = [num2str(D) '-D'];
end
if isempty(val) == 0
prefix = [name ': ' theSize ' ' class(val)];
else
prefix = [name ': empty ' theSize ' ' class(val)];
end
end
% Some other stuff
end
And it's the prefix
function that we'll edit in order to do what we want to do, along with some filescanning and string comparison in the initialization phase :
A) Initialization phase :
% Read data from csv file :
fid = fopen('ToyVars.csv');
Data = textscan(fid, '%s%s','whitespace','','delimiter',';');
fclose(fid);
B) Compare the name of the variable you're hovering on with the names of the variables in Data
NameFound=0;
% Get Variable Names and Corresponding comments
TmpNames=Data{1,1};
TmpComments=Data{1,2};
% Loop through TmpNames. If a Name matches, assign corresponding comment to the variable Comment
for ii=1:size(TmpNames,1)
if(isequal(char(TmpNames(ii))),name)
Comment=char(TmpComments(ii));
NameFound=1;
end
end
C) Add the comment in the datatip if NameFound==1
if NameFound
if isempty(val) == 0
prefix = [name ': ' theSize ' ' class(val) ' : ' Comment];
else
prefix = [name ': empty ' theSize ' ' class(val) ' : ' Comment];
end
else
if isempty(val) == 0
prefix = [name ': ' theSize ' ' class(val)];
else
prefix = [name ': empty ' theSize ' ' class(val) ];
end
end
And voilà!
With a slight tweak and some modifications to the calling function you can also utilize @BillBokeey's answer without any external dependencies. By placing a structure array in the same workspace as the variable you are previewing, you can store a string in a field with the same name as your variable and utilize evalin
with the existing logic in datatipinfo
to get the inputs for @BillBokeey's modifications.
For my test case I am storing my strings in a structure named mydatastrings
:
mydatastrings.test = 'Test Variable';
In the body of datatipinfo
I have added a try
block:
NameFound = 0;
try
Comment = evalin('caller', sprintf('mydatastrings.%s', name));
NameFound = 1;
end
Along with @BillBokey's modifications to the nested prefix
function:
if NameFound
if isempty(val) == 0
prefix = [name ': ' theSize ' ' class(val) ' : ' Comment];
else
prefix = [name ': empty ' theSize ' ' class(val) ' : ' Comment];
end
else
if isempty(val) == 0
prefix = [name ': ' theSize ' ' class(val)];
else
prefix = [name ': empty ' theSize ' ' class(val) ];
end
end
And we achieve the same results.
Full files are in this Gist
EDIT:
You can also make a minimal adjustment to datatipinfo
to display a comment without modifying prefix
. It seems like whatever executes datatipinfo
also captures all of the outputs to the command window and displays them in the popup rather than the command window itself.
If we replace the previous try
block with simply:
try
Comment = evalin('caller', sprintf('mydatastrings.%s', name))
end
And leave prefix
as it is in the default MATLAB install, we obtain the following popup:
This is also included in the Gist as datatipinfo_noprefix.m
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With