在Matlab的命令行中运行特定的单元格部分? [英] Run particular cell section from command line in Matlab?

查看:104
本文介绍了在Matlab的命令行中运行特定的单元格部分?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在脚本中手动遍历Matlab中的各个单元格(我们称它为foo.m):

I am cycling through various cells in Matlab by hand in a script (let's call it foo.m):

%%
%Code for cell 1

%%
%Code for cell 2

从Matlab的命令行中,我希望能够在单元2中有选择地运行代码.

From the command line of Matlab, I would like to be able to selectively run the code in cell 2. The documentation only has instructions for how to do it interactively (e.g., place the cursor in the appropriate cell, then blah blah). I would like something for the command line so I can do something like foo.runCell(1) to run the code in cell 1 above.

如果没有办法,我将把这些单元分解成单独的脚本/函数.这不太方便,因为我处于快速研修原型"的编码模式下,因此现在将所有内容都存储在一个文件中.

If there is no way to do it, I will just split the cells up into separate scripts/functions. This is less convenient, as I am in a 'grind out prototype very quickly' mode of coding, so want everything in one file for now.

推荐答案

Dev-iL 使用Java等提供了很好的答案...在此我将提供一种不使用Java或编辑器,但会读取文件并在需要时评估语句.

Dev-iL has provided a good answer using java etc... I will provide an alternative here which does not use java or the editor, but reads the file and evals the statements when requested.

要使其正常工作,必须预先保存文件(我知道这不是交互式运行单元格/代码块的先决条件).

无论如何,我认为这是一个古怪"的问题,并且想补充一下.

Anyway I thought this was a "quirky" question and thought I'd add have a go at an answer.

这是我的脚本(cellScript.m),其中包含代码块(请注意,我在"%%"之后给每个块起了一个名字:

Here is my script (cellScript.m) which contains code blocks (Note I have given each block a name after the "%%":

%Note: for this method your NOT allowed to put comments at the end of lines
%% cellA
disp ( 'running cell A' ); 
disp ( 'finished cell A' );
%% cellB
disp ( 'running cell B' );
disp ( 'finished cell B' );
%% cellC
disp ( 'running cell C' );
for ii=1:100
  aa(ii) = randi(1);
end
% cells can have comments
disp ( 'past 1st coment' );
   % cells comments can be indented
disp ( 'past indented comment' );

  %{
   block 
   comment
  %}
disp ( 'past block comment' );

% cells can have comments
% multiple lines of comments
  % not lined up
%
%and empty

disp ( 'past multiple lines of comments' );

disp ( 'finished cell C' );
%% cellD
disp ( 'running cell D' );

disp ( 'finished cell D' );
%% cellE
disp ( 'running cell E' );
disp ( 'finished cell E' );

我创建了一个可以完成所请求工作的类(我称其为cellRunner.m)

I have created a class which does the job requested (I called it cellRunner.m )

classdef cellRunner < handle
  properties ( SetAccess = private )
    fileName
    fileInfo
    cellInfo
    cellNames = {};
  end
  methods 
    function obj = cellRunner ( file ) % constructor
      if nargin == 0                        
        obj.fileName = 'cellScript.m';      % default file for testing
      else
        obj.fileName = file;                % store user file
      end
      obj.parseFile();                      % read the file into memory
    end
    function obj = parseFile ( obj )
      if ~isempty ( obj.fileInfo )                        % on parsing check to see if its been parsed before
        if isequal ( obj.fileInfo, dir ( obj.fileName ) ) % Check date stamp (has cell file been modified
%           disp ( 'file not changed - reading skipped' );  % if not skip
%           reading 
          return
        end
      end
      obj.fileInfo = dir ( obj.fileName );                % store file info
      fid = fopen ( obj.fileName );                       % open file for reading
      if fid ~= -1
        index = 0;                                        % this is the index of each cell
        inCell = false;                                   % has it found a cell to start reading
        lines = cell(0);                                  
        while ( true )
          line = fgetl ( fid );                           % read the line in the file
          if line == -1; break; end                       % check for the end of the file
          sLine = strtrim ( line );                       % trim any white space
          if length ( sLine ) > 2 && strcmp ( sLine(1:2), '%%' ) % check to see if its the start of a cell
            if index > 0                                  % Store the last cell data                
              obj.cellInfo{index} = lines;                % in class to run when required
            end
            index = index + 1;                            % increment the index
            obj.cellNames{index} = strtrim ( sLine(3:end) ); % save the name of the cell
            lines = cell(0);                              % re-initialise the lines var
            inCell = true;                                % the start of the cells have been found
          elseif inCell                                   % if reading a cell array
            lines{end+1} = line;                          % add each line to the lines var
          end          
        end
        if index > 0                                      % make sure and save the last cell when finished reading
          obj.cellInfo{index} = lines;
        end
        fclose ( fid );
      else
        error ( 'cellRunner:fileError', 'unable to read file' );
      end
    end
    function obj = runCell ( obj, arg )
      % obj.runCell ( 'cellName' );
      % obj.runCell ( index );
      obj.parseFile();                                    % check that the file hasn't been changed
      if ischar ( arg )                                   % if user provided a char then search for it
        index = strcmp ( arg, obj.cellNames );            % find the index
        if ~any ( index )                                 % check it was found
          error ( 'cellRunner:notFound', '%s not found', arg ); 
        end
      else
        index = arg;                                      % if index is an integer (not checked - assumed if not char)
        if index < 1 || index > length ( obj.cellInfo )   % check integer is valid
          error ( 'cellRunner:notFound', 'Index %d not found', arg );
        end
      end
      commands = obj.cellInfo{index}{1};                  % start to build the command to execute.
      inBlock = false;
      for ii=2:length(obj.cellInfo{index})                % loop around - ignoring any commented lines.
        nextLine = strtrim ( obj.cellInfo{index}{ii} ); 
        if inBlock
          if length ( nextLine ) == 2 && strcmp ( nextLine, '%}' );
            inBlock = false;
          end
          continue
        end
        if length ( nextLine ) == 2 && strcmp ( nextLine, '%{' );
          inBlock = true;
          continue
        end
        if length ( nextLine ) >= 1 && strcmp ( nextLine(1), '%' )
          continue;
        end
        commands = sprintf ( '%s;%s', commands, obj.cellInfo{index}{ii} ); % build a parge string to eval
      end
      evalin('base',commands);                            % eval the expression in the base workspace.
    end
  end
end

然后使用以下代码:

obj.cellRunner();
% Individual cells can be run in two ways:

% By providing the name of the cell (the string after the %%)
obj.runCell ( 'cellC' );
% By providing the index
obj.runCell ( 3 );

注意:必须保存文件才能使该文件正常工作.

Note Recall the file must be saved for this to work.

样品运行:

whos
obj = cellRunner ( 'cellScript.m' );
obj.runCell ( 'cellC' );
running cell C
past 1st coment
past indented comment
past block comment
past multiple lines of comments
finished cell C
whos
  Name      Size             Bytes  Class         Attributes

  aa        1x100              800  double                  
  ans       1x1                112  cellRunner              
  ii        1x1                  8  double                  
  obj       1x1                112  cellRunner              

注释1-为什么要处理类?我继承了处理类,因为我只希望读取文件数据的一个副本-请参见

Note 1 - Why handle class? I inherit from the handle class because I only want one copy of my file data that has been read - see answer 1 in this question for an excellent overview of when to use value/handle classes.

这篇关于在Matlab的命令行中运行特定的单元格部分?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆