[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: findobj.m
From: |
David Bateman |
Subject: |
Re: findobj.m |
Date: |
Thu, 27 Sep 2007 01:56:30 +0200 |
User-agent: |
Thunderbird 1.5.0.7 (X11/20060921) |
Ben Abbott wrote:
> I've written a Octave script that is intended to mirror the functionality of
> Matlab's findobj function.
>
> Assuming there is no Octave version of findobj at the present time, I'm happy
> to submit it for that purpose.
>
> Although I did make a modest attempt to include the proper copyright and help
> at the top of the script, I expect some additional effort is required to
> bring it up to standards.
>
> In any event, it is attached.
>
>
>
Well, some points..
1) The help string should be in texinfo as this is a core function and
needs to be formated for the Octave manual itself
2) You should use "#" as the comment character. "##" for comments
aligned with the code and "#" for indented comments.
3) I doubt the depth of 1e9 will ever be reach but using NaN instead for
the depth would be cleaner and the > and < operators always return false
for expressions involving NaN
4) Use "!=" and not "~=".
5) I think in the "strcmpi(args{na}, '-property')" if statement you had
a "np=np+1" that is redundant as it is replicated outside the if statement.
6) Although there is no coding style guide for Octave, there are fairly
strict ideas about what functions in Octave itself should look like.
Some examples
* No camelcase argument name Depth should be depth
* spacing between arguments of functions
* Use of the block specific terminations of Octave, endif, endfor, etc
* Functions must be terminated with endfunction
There are others I'm sure, and if you look at some of the function in
Octave you'll get the idea of what they are
I've tried to do these conversions to your code, but haven't tested the
function afterwards. In any case I wonder how fast this function will
be? Matlab has implemented this as a builtin function, maybe it should
be for Octave as well.
I'm not sure the regexp code works as expected, as some test cases I
tried didn't give the expected results as they returned objects that
didn't even have the property..
D.
## Copyright (C) 2007 Ben Abbott <address@hidden>
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
## 02110-1301 USA
## -*- texinfo -*-
## @deftypefn {Function File} address@hidden =} findobj ()
## @deftypefnx {Function File} address@hidden =} findobj (@var{propName},
@var{propValue})
## @deftypefnx {Function File} address@hidden =} findobj ('-property',
@var{propName})
## @deftypefnx {Function File} address@hidden =} findobj ('-regexp',
@var{propName},, @var{pattern})
## @deftypefnx {Function File} address@hidden =} findobj ('flat', @dots{})
## @deftypefnx {Function File} address@hidden =} findobj (@var{h}, @dots{})
## @deftypefnx {Function File} address@hidden =} findobj (@var{h}, '-depth',
@var{d}, @dots{})
## Find object with specified property values. The simpliest form is
##
## @example
## findobj (@var{propName}, @var{propValue})
## @end example
##
## @noindent
## which returns all of the handles to the objects with the name
## @var{propName} and the name @var{propValue}. The search can be limited
## to a particular object or set of objects and their descendants by
## passing a handle or set of handles @var{h} as the first argument to
## @code{findobj}.
##
## The depth of hierarchy of objects to which to search to can be limited
## with the '-depth' argument. To limit the number depth of the hierarchy
## to search to @var{d} generations of children, and example is
##
## @example
## findobj (@var{h}, '-depth', @var{d}, @var{propName}, @var{propValue})
## @end example
##
## Specifying a depth @var{d} of 0, limits the search to the set of object
## passed in @var{h}. A depth @var{d} of 0 is equivalent to the '-flat'
## argument.
##
## A specified logical operator may be applied to the pairs of @var{propName}
## and @var{propValue}. The supported logical operators are '-and', '-or',
## '-xor', '-not'.
##
## The objects may also be matched by comparing a regular expression to the
## property values, where property values that match @code{regexp
## (@var{propValue}, @var{pattern})} are returned. Finally, objects may be
## matched by property name only, using the '-property' option.
## @seealso{get, set}
## @end deftypefn
function h = findobj (varargin)
depth = NaN;
if (nargin == 0)
handles = 0;
n1 = 0;
else
if (ishandle (varargin{1}(1)))
handles = varargin{1};
n1 = 2;
else
handles = 0;
n1 = 1;
end
if (n1 <= nargin)
if (ischar (varargin{n1}))
if (strcmpi (varargin{n1}, 'flat'))
depth = 0;
n1 = n1 + 1;
elseif (strcmpi(varargin{n1}, '-depth'))
depth = varargin{n1+1};
n1 = n1 + 2;
endif
else
error ("findobj: properties and options must be strings");
endif
endif
endif
if (n1 <= nargin && nargin > 0)
args = varargin(n1 : nargin);
else
args = {};
endif
regularexpression = [];
property = [];
logicaloperator = {};
pname = {};
pvalue = {};
np = 1;
na = 1;
while (na <= numel (args))
regularexpression(np) = 0;
property(np) = 0;
logicaloperator{np} = 'and';
if (ischar (args {na}))
if (strcmpi(args{na}, '-regexp'))
regularexpression(np) = 1;
na = na + 1;
elseif (strcmpi(args{na}, '-property'))
na = na + 1;
property(np) = 1;
pname{np} = args{na};
na = na + 1;
pvalue{np} = [];
elseif (! strcmp (args{na}(1), '-')) # parameter/value pairs
pname{np} = args{na};
na = na + 1;
pvalue{np} = args{na};
na = na + 1;
if (na <= numel(args))
if (ischar (args{na}))
if strcmpi(args{na}, '-and')
logicaloperator{np} = 'and';
na = na+1;
elseif strcmpi(args{na}, '-or')
logicaloperator{np} = 'or';
na = na+1;
elseif strcmpi(args{na}, '-xor')
logicaloperator{np} = 'xor';
na = na+1;
elseif strcmpi(args{na}, '-not')
logicaloperator{np} = 'not';
na = na+1;
endif
else
error ("findobj: properties and options must be strings");
endif
else
logicaloperator{np} = 'and';
endif
np = np + 1;
else
## this is sloppy ... but works like matlab
if strcmpi(args{na}, '-not')
h = [];
return
endif
na = na + 1;
endif
else
error ("findobj: properties and options must be strings");
endif
endwhile
numpairs = np - 1
## load all objects which qualify for being searched
idepth = 0;
h = handles;
while (numel (handles) && ! (idepth >= depth))
children = [];
for n = 1 : numel (handles)
children = union (children, get(handles(n), 'children'));
endfor
handles = children;
h = union (h, children);
idepth = idepth + 1;
endwhile
keepers = ones (size (h));
if (numpairs > 0)
for nh = 1 : numel(h)
p = get (h (nh));
for np = 1 : numpairs
fields = fieldnames (p);
fieldindex = find (strcmpi (fields, pname{np}), 1);
if (numel (fieldindex))
pname{np} = fields{fieldindex};
if (property(np))
match = 1;
else
if (regularexpression(np))
match = regexp (p.(pname{np}), pvalue{np});
elseif (numel (p.(pname{np})) == numel (pvalue{np}))
if (ischar (pvalue{np}))
match = strcmpi (pvalue{np}, p.(pname{np}));
else
match = (pvalue{np} == p.(pname{np}));
endif
else
match = 0;
endif
match = all (match);
end
if (strcmpi (logicaloperator{np}, 'not'))
keepers(nh) = ! keepers(nh) & ! match;
else
keepers(nh) = feval (logicaloperator{np}, keepers(nh), match);
endif
endif
endfor
endfor
endif
h = h (keepers != 0);
h = reshape (h, [numel(h), 1]);
endfunction
- findobj.m, Ben Abbott, 2007/09/19
- findobj.m, Ben Abbott, 2007/09/26
- Re: findobj.m, David Bateman, 2007/09/26
- Re: findobj.m,
David Bateman <=
- Re: findobj.m, Ben Abbott, 2007/09/29
- Re: findobj.m, David Bateman, 2007/09/30
- Re: findobj.m, John W. Eaton, 2007/09/30
- Re: findobj.m, David Bateman, 2007/09/30