MATLAB Answers

0

How do I verify user input from prompt/inputdlg and go back to same prompt if input is invalid?

Jason Newman さんによって質問されました 2019 年 3 月 4 日
最新アクティビティ Rik
さんによって コメントされました 2019 年 3 月 5 日
We are in the process of adding some gui elements to update one of our text based scripts. Some of the input values must be a number or an integer. With the input command at the command line, there are various ways to validate the input and have the question be asked again before the rest of the program proceeds.
While I can do a similar validation for the prompt command, where I am stuck is how to get the script to loop back to the same prompt if the response to the prompt is not valid. In the example below, the script displays an error message and then ends if the user did not enter an integer for the matrix size. That's okay for small programs, but in our project, it will be frustrating for a user to have to start over if they make a mistake towards the end of the script. How do I get the script to loop back to the prompt where the mistake occurred instead of having to start over (it is probably a good idea to still display the error message though). Thanks!
% input dialog box example
% do something with the input. Display an error message if matrix size
% input is not an integer
close all
clear
clc
promt={'Enter matrix size as an integer:','Enter your figure name:'};
title='Input';
dims=[1 35];
definput={'200','RGB noise'}; %makes a square matrix to keep things simple
answer=inputdlg(promt,title,dims,definput); %creates an array with input. Next is to extract input and do something
matrixsizeinput=answer{1,1}; % if everything in array is in rows, specifying columns is not absolutely necessary
matrixsize=str2double(matrixsizeinput); %str2double is preferred over str2num
if isreal(matrixsize) && rem(matrixsize,1)==0 %evaluates whether matrix size entered is an integer
else
msgbox('The value you entered for the matrix size was not an integer. Please rerun program.','Error!','error');
return %halts the program since maxtrixsize is not an integer
end %ends integer evaluation. Rest of program runs if maxtrixsize is an integer
figtitle=answer{2,1}; %gets the figure title which is a string
% result=zeros(matrixsize,matrixsize); %this makes a matrix filled with zeroes depending on the input
result=randi(256,matrixsize,matrixsize,3);
figure('Name',figtitle);
imshow(uint8(result)); %must specify that values are 8 bit RGB, otherwise numbers in array are read as intensity

  2 件のコメント

Just some small remarks:
The uint8 data type only supports digits up to 255, so your random RGB matrix will be slightly biased, as 256 will be rounded to 255.
You should use functions to keep your workspace clean, instead of using the clear function. You should also consider if it is reasonable for the user to have other figures open, which they might not want to close.
Thank you for pointing out the unit8 issue.

サインイン to comment.

製品


リリース

R2018a

1 件の回答

回答者: Rik
2019 年 3 月 4 日
 採用された回答

One of the ways to solve this is with a recursive function. (another solution you could choose is a while loop)
function matrixsize=prompt_user__matrix_size
promt={'Enter matrix size as an integer:','Enter your figure name:'};
title='Input';
dims=[1 35];
definput={'200','RGB noise'}; %makes a square matrix to keep things simple
answer=inputdlg(promt,title,dims,definput); %creates an array with input. Next is to extract input and do something
matrixsizeinput=answer{1,1}; % if everything in array is in rows, specifying columns is not absolutely necessary
matrixsize=str2double(matrixsizeinput); %str2double is preferred over str2num
if ~( isreal(matrixsize) && rem(matrixsize,1)==0 )
%show error and restart prompt
msgbox('The value you entered for the matrix size was not an integer.','Error!','error');
matrixsize=prompt_user__matrix_size;
end
end

  7 件のコメント

This works as expected on my copy of R2018a:
uiwait(msgbox('The value you entered for the matrix size was not an integer. Please rerun program.','Error!','error'))
As for your error: why are you mixing input and processing again? The whole point of such an input function is to separate them, so you can keep everything clear. The functions below show what I mean. I also shortened the lines to a max of 75 chars (you can do a bit larger if you like, but short lines keep code clear). I also added a comment about clc,clear,close all. It might also be usefull to know that there is a difference between a string and a char. It is a bit annoying that Mathworks created a data type with this name a few years back, because now it is not clear if someone means a char array or a string.
function SomeFunction
% input dialog box example
% do something with the input. Display an error message if matrix size
% input is not an integer
%Don't use this outside of debugging. Use functions to keep your workspace
%clean, use explicit figure/axes handles to create graphics objects (your
%user might have other relevant figures open), and don't rely on the
%command window output to show vital information to your user.
close all
clear
clc
[matrixsize,figtitle]=prompt_user__matrix_size;
result=uint8(randi(255,matrixsize,matrixsize,3));
figure('Name',figtitle);
imshow(result);
end
function [matrixsize,figtitle]=prompt_user__matrix_size
promt={'Enter matrix size as an integer:','Enter your figure name:'};
title='Input';
dims=[1 35];
%makes a square matrix to keep things simple
definput={'200','RGB noise'};
%creates an array with input. Next is to extract input and do something
answer=inputdlg(promt,title,dims,definput);
matrixsizeinput=answer{1}; %get the size (still as a char array)
figtitle=answer{2}; %gets the figure title which is a char array
matrixsize=str2double(matrixsizeinput); %str2double is better than str2num
if ~( isreal(matrixsize) && rem(matrixsize,1)==0 )
%show error and restart prompt
uiwait(msgbox(...
'The value you entered for the matrix size was not an integer.',...
'Error!','error'));
[matrixsize,figtitle]=prompt_user__matrix_size;
end
end
Thanks. I accidently put uiwait on it's own line, so that was the reason for the problem.
You are correct... I should start with a script that calls upon the function rather than mixing the function and the results. I suspect that if I spend a little more time working that out, I should be able to get it to work,
I've only been doing this for the last 6-8 months, and the online class I took was a bit weak on the fucntion side of this to get input and pass the results on to something else.
This was proof of concept, and I feel your replies have answered my question. Thanks.
You're welcome.
As a sidenote I would urge you to keep up with this amount of comments in your code. I can imagine it might feel a bit excessive at times, but it really helps other people understand the code you wrote. And you in 6 months or a year is also counts as someone else.

サインイン to comment.



Translated by