# Coding challenge on input parsing 3

Posted by **Jiro Doke**,

Jiro's pick this week is boundedline by Kelly Kearney. Today, there's also a fun challenge at the end!

### Contents

### boundedline

Kelly is a veteran of the File Exchange, with a number of great entries, many of which have high ratings. I realized I had already picked one of her entries, `legendflex`. Going back and reading that post and looking through her code for `legendflex`, I realized why I like her entries. Kelly's programs are

- well-written, with great help.
- flexible, with many options.
- robust, with good error checking.

Just type

`help boundedline`

and you'll see what I mean. `boundedline` is a nice function that allows you to plot lines with shaded bounds, that can represent error or confidence bounds.

She acknowledges a few other File Exchange entries, a couple of which have been picked previously as a Pick of the Week. `boundedline` has additional capabilities that make it unique.

### Challenge

But today, I'd like to focus on one aspect of this entry, namely input parsing and error checking. As you can see from the
help for the function, you can call `boundedline` in various ways:

[hl, hp] = boundedline(x, y, b) [hl, hp] = boundedline(x, y, b, linespec) [hl, hp] = boundedline(x1, y1, b1, linespec1, x2, y2, b2, linespec2) [hl, hp] = boundedline(. . ., 'alpha') [hl, hp] = boundedline(. . ., ax) [hl, hp] = boundedline(. . ., 'transparency', trans) [hl, hp] = boundedline(. . ., 'orientation', orient) [hl, hp] = boundedline(. . ., 'cmap', cmap)

There are some required inputs, some optional inputs, and some optional parameter-value inputs. In order to make this work,
Kelly parses the inputs and makes sure that the inputs are all valid. But she doesn't use `inputParser` or `validateattributes`. I know that she knows about these functions, because she used them in her other entry, `legendflex`. Perhaps she didn't know about them when she wrote `boundedline`.

So my challenge to everyone is to come up with some code that would do the appropriate input parsing and error checking on
the inputs using `inputParser`. Feel free to use various error-checking functions, such as `validateattributes`.

Now, I haven't done this myself, but I can envision for the most part how I would go about doing this. However, I'm struggling with the 3rd calling syntax above. So I'm going to make that an extra credit. Here are the rules/requirements:

- The function should be able to handle all, except the 3rd, calling syntax above. Any number of the optional arguments can be passed in.
- The input parameters should meet the respective criteria. (see help boundedline)
- All optional inputs should have default values. (see help boundedline)
- You can assume that the parameter-value pair inputs will be called after the other optional inputs.
- After parsing, the parameters should be put into a structure with fields "x", "y", "b", "linespec", "usealpha", "hax", "trans", "orient", "cmap".
- (Extra credit) Allow for the 3rd calling syntax.

That's it! Put your thinking hat on, and post your solutions here to win some MATLAB swag! I will write another post highlighting some of the solutions I get.

Please post the code answer as a function that takes in `varargin` as an input and returns `strct` (with appropriate fields) as an output. Be sure to use the "code" markup so that your code will be easier to read:

<pre class="code"> funtionc strct = validateIntputs(varargin) ... end </pre>

Get the MATLAB code

Published with MATLAB® R2012b

**Category:**- Picks

## 3 CommentsOldest to Newest

**1**of 3

Here’s my effort:

ipObj1 = inputParser; ipObj1.addRequired('x',@(x)validateattributes(x,{'numeric'},{'finite','2d'})); ipObj1.addRequired('y',@(x)validateattributes(x,{'numeric'},{'finite','2d'})); ipObj1.addRequired('b',@(x)validateattributes(x,{'numeric'},{'finite'})); keys = {'transparency','orientation','cmap'}; res = ''; res_ipObj2 = ''; res_ipObj3 = ''; try ipObj2 = ipObj1.createCopy; ipObj2.addOptional('linespec','',@(x)ischar(x) && ~any(strcmp(x,{'alpha',keys{:}}))); ipObj2.addOptional('useAlpha','',@(x)strcmp(x,'alpha') || ishandle(x)); ipObj2.addOptional('hax','',@(x)strcmp(x,'alpha') || ishandle(x)); ipObj2.addParamValue('orientation','horiz',@(x)any(validatestring(x,{'horiz','vert'}))); ipObj2.addParamValue('transparency',0.2,@(x)validateattributes(x,{'numeric'},{'scalar','positive'})); ipObj2.addParamValue('cmap',[],@(x)validateattributes(x,{'numeric'},{'2d','finite','size',[size(x,1),3]})); ipObj2.parse(varargin{:}); res_ipObj2 = ipObj2.Results; res = res_ipObj2; catch me try ipObj3 = ipObj1.createCopy; ipObj3.addOptional('linespec','',@(x)ischar(x) && ~any(strcmp(x,{'alpha',keys{:}}))); ipObj3.addOptional('x1',[],@(x)validateattributes(x,{'numeric'},{'finite','2d'})); ipObj3.addOptional('y2',[],@(x)validateattributes(x,{'numeric'},{'finite','2d'})); ipObj3.addOptional('b2',[],@(x)validateattributes(x,{'numeric'},{'finite'})); ipObj3.addOptional('linespec2','',@(x)ischar(x) && ~any(strcmp(x,{'alpha',keys{:}}))); ipObj3.addOptional('useAlpha','',@(x)strcmp(x,'alpha') || ishandle(x)); ipObj3.addOptional('hax','',@(x)strcmp(x,'alpha') || ishandle(x)); ipObj3.addParamValue('orientation','horiz',@(x)any(validatestring(x,{'horiz','vert'}))); ipObj3.addParamValue('transparency',0.2,@(x)validateattributes(x,{'numeric'},{'scalar','positive'})); ipObj3.addParamValue('cmap',[],@(x)validateattributes(x,{'numeric'},{'2d','finite','size',[size(x,1),3]})); ipObj3.parse(varargin{:}) res_ipObj3 = ipObj3.Results; res = res_ipObj3; catch me2%345345 res_ipObj3 = ''; end res_ipObj2 = ''; end if isempty(res_ipObj2) && isempty(res_ipObj3) try ipObj4 = ipObj1.createCopy; ipObj4.addOptional('useAlpha','',@(x)strcmp(x,'alpha') || ishandle(x)); ipObj4.addOptional('hax','',@(x)strcmp(x,'alpha') || ishandle(x)); ipObj4.addParamValue('orientation','horiz',@(x)any(validatestring(x,{'horiz','vert'}))); ipObj4.addParamValue('transparency',0.2,@(x)validateattributes(x,{'numeric'},{'scalar','positive'})); ipObj4.addParamValue('cmap',[],@(x)validateattributes(x,{'numeric'},{'2d','finite','size',[size(x,1),3]})); ipObj4.addOptional('linespec','',@(x)ischar(x) && ~any(strcmp(x,{'alpha',keys{:}}))); ipObj4.parse(varargin{:}); res = ipObj4.Results; catch me error(me.identifier,me.message) end end if ishandle(res.useAlpha) tmp1 = res.useAlpha; tmp2 = res.hax; res.hax = tmp1; res.useAlpha = tmp2; end

**2**of 3

Sorry, I didn’t put my code inside a function.

function res = validateInputs(varargin)

%%%code%%%

end

**3**of 3

Thanks Mikko for your entry! I will parse through this and write up an entry on this.

Let me send you an email to get your contact info so that we can send you some MathWorks gifts!

## Recent Comments