Print the current line of code and the names, types and sizes of specific variables

To debug my Octave / MATLAB code, I want to be able to do something like:

A = magic(3);
b = 42;
describe(@A, @b);

and get the output, for example:

filename.m line 3: "A" is a 3x3 matrix
filename.m line 3: "b" is a scalar of value: 42

For several variables, how can I type:

  • Function file and line call
  • Name
  • Enter
  • Dimensions
+4
source share
3 answers

Overview

In this answer, I list 3 subtle versions of the function describe.

  • It takes any number of variables and creates an output string and displays it with fpritnf
  • It takes any number of variables and creates an output array of cells and displays it usingdisp
  • Accepts any number of variables , 1. , , describe('myvar{1}').

1.

, :

  • varargin
  • dbstack, /
  • inputname, , describe
  • fprintf
  • varargout

, describe :

function varargout = describe(varargin)
    % varargin used to accomodate variable number of inputs
    % By default, at least get functions stack (even if no variables are passed in)
    st = dbstack;
    % Convert cell output to string (excluding describe.m itself)
    outstring = '';
    % Loop backwards for more logical order (most recent last)
    for ii = size(st, 1):-1:2
        % new line character at end only works with fprintf, not disp
        outstring = [outstring, st(ii).file, ' > ', st(ii).name, ...
                     ', line ', num2str(st(ii).line), '\n'];
    end
    % Loop over variables and get info
    for n = 1:nargin
        % Use inputname to get name of input variables
        outstring = [outstring, '"', inputname(n), '" is a ', ...
                     class(varargin{n}), ' of size ', mat2str(size(varargin{n})), '\n'];
    end
    % If output variable is requested then assign to output variable
    % If not, just display output string to command window 
    if nargout 
        varargout{1} = outstring;
    else
        fprintf(outstring)
    end
end 

, , - , , , , , .


:

% In myMainFunction.m, in the subfunction mySubFunction
% Could store output using 'd = describe(A,B);' and use 'fprintf' later 
describe(A, B);
% In the command window
myMainFunction.m > myMainFunction, line 3
myMainFunction.m > mySubFunction, line 39
"A" is a double of size [1 3]
"B" is a double of size [1 5 9 7]

Matlab R2015b, , R2006a , , Octave.


2.

.

, , , , , , fprintf . , ( ) .

function varargout = describe(varargin)
    st = dbstack; outcell = {};
    for ii = size(st, 1):-1:2
        outcell{end+1} = [st(ii).file, ' > ', st(ii).name, ', line ', num2str(st(ii).line)];
    end
    for n = 1:nargin
        outcell{end+1} = ['"', inputname(n), '" is a ',  class(varargin{n}), ' of size [', size(varargin{n}), ']'];
    end
    outcell = outcell.'; % Transpose to make it a column cell array
    disp(outcell)
end 

3.

, , 'myvar(1)'.

evalin caller ( describe). . , describe, .

function varargout = describe(varargin)
    % varargin used to accomodate variable number of input names
    st = dbstack;
    outstring = '';
    for ii = size(st, 1):-1:2
        outstring = [outstring, st(ii).file, ' > ', st(ii).name, ', line ', num2str(st(ii).line), '\n'];
    end
    % Loop over variables and get info
    for n = 1:nargin
        % Variables are passed by name, so check if they exist
        try v = evalin('caller', varargin{n});
            outstring = [outstring, '"', varargin{n}, '" is a ', class(v), ' of size ', mat2str(size(v)), '\n'];   
        catch
            outstring = [outstring, 'Variable "', varargin{n}, '" not found!\n'];
        end
    end
    fprintf(outstring)
end 

:

% This can be used with indexed variables too. MUST PASS STRINGS!
describe('C{1}', 'B(1:2, :)')
% In the command window
myMainFunction.m > myMainFunction, line 3
myMainFunction.m > mySubFunction, line 39
"C{1}" is a double of size [1 3]
"B(1:2, :)" is a double of size [2 5]

% Because you're passing strings, you can use command syntax if you want
% Gives same result but don't have to pass strings 
% as that how inputs are interpreted anyway for command syntax.
describe C{1} B(1:2, :)
+5

. :

function describe(A)
  fprintf('       Class : %s\n',class(A));
  fprintf('  Num. Elems : %s\n',num2str(numel(A)));  
  fprintf('        Size : %s\n',num2str(size(A)));
  fprintf('   Total Min : %s\n',num2str(min (A(:))));
  fprintf('   Total Max : %s\n',num2str(max (A(:))));  
  fprintf('   Total Sum : %s\n',num2str(sum (A(:))));
  fprintf('  Total Mean : %s\n',num2str(mean(A(:))));
  fprintf('Total St.Dev : %s\n',num2str(std (A(:), 1)));
  fprintf(' Unique vals : %s\n',num2str(length(unique(A))));  
end

: , , , .:)


< > PS. , , - ​​ : , ( keyboard) , , , linenumber ! , ? "" , !

, , , ; , .

+1

You can use sizeto have the size of your variable, for the type use classand to use the name inputname. For instance:

function describe(a)
  s = size(a); % Return the size of a
  t = class(a); % Return the type of a
  name = inputname(1); % Return the name of a

  printf(['filename.m line 3: ''''' name ''''' size:' s(1) 'x' s(2) ' and type: ' t]);
end

I don’t know how to use the file name and string, and if you want another way to show this, you can use the condition to separate the scalar from the vector from the matrix.

0
source

Source: https://habr.com/ru/post/1682388/


All Articles