Error handling with inputdlg - matlab

Below is an input dialog box I'm using in a program. Does anyone know
how to "nicely" handle the case when the user input is not a number?
Also, if the number is outside the range minlev - maxlev then the
error dialog pops up, but you cannot press the OK button because the
input dialog pops up in front of it. Does anyone know how to fix
this?
RVP= 1;
while ( RVP )
prompt = {'Enter the corridor width (1050-1400mm) :'};
dlg_title = 'Input';
num_lines=1;
answer = inputdlg(prompt,dlg_title,num_lines);
if(str2num(answer{1})<1050 || (str2num(answer{1})>1400))
errordlg('Number is out of range');
else
w1 = (2*answer{1}-1050-1400)/(1400-1050)
end
end

Use isnumeric. Then you can re-call the inputdlg after the error dialog.
To keep the errordlg box from being covered up, use uiwait.
while ( RVP )
prompt = {'Enter the corridor width (1050-1400mm) :'};
dlg_title = 'Input';
num_lines=1;
answer = inputdlg(prompt,dlg_title,num_lines);
if ~isnumeric(answer) || (str2num(answer{1})<1050 || (str2num(answer{1})>1400))
uiwait(errordlg('Number is out of range'));
answer = inputdlg({'Please enter a valid input (1050-1400mm) :'},...
dlg_title,num_lines);
end
w1 = (2*answer{1}-1050-1400)/(1400-1050)
end

Related

How do I define a variable from another function?

I have a multi-fuction script that is supposed to ask the user for 4 different cars and weigh them based on ratings to give the user the best car to purchase.
What I want to do is have a prompt for every car the user inputs so the user can put in data for each variable the user decides to use. However, when titling the prompt I want to use the cars name in the prompt. It seems impossible to me and Im not sure what to do, im very new to coding.
Main Script
prompt1 = {'How Many Cars (4): '};
title1 = 'Cars';
answer1 = inputdlg(prompt1, title1, [1 40]);
Q1 = str2double(answer1{1});
[N] = Group_Function1(Q1);
Car1 = N(1); %Stores the names of the cars
Car2 = N(2);
Car3 = N(3);
Car4 = N(4);
prompt2 = {'How Many Variables (4): '};
title2 = 'Variables';
answer2 = inputdlg(prompt2, title2, [1 50]);
fprintf('This code can accept costs between 0-100000\n');
fprintf('This code can accept top speeds between 0-200\n');
fprintf('This code can also accept the terms none, some, & alot\n');
fprintf('This code can accept safety ratings between 0-5\n');
Q2 = str2double(answer2{1});
[V,W] = Group_Function2(Q2);
W1 = W(1); %Stores the weights of the varibles
W2 = W(2);
W3 = W(3);
W4 = W(4);
for h=1:Q1
[H] = Group_Function3(V);
Weights(h,:)=H;
end
Group_Function1
function [N] = Group_Function1(Q1)
for Q = 1:Q1
prompt = {'Name of Car:'};
title = 'Car Name';
answer = inputdlg(prompt,title, [1 80])';
N(Q) = answer(1);
end
Group_Function2
function [V,W] = Group_Function2(Q2)
for Q=1:Q2
prompt = {'Variable? (Negative Variables First):','weights in decimal
form?'};
title = 'Variables and Weights';
answer = inputdlg(prompt,title, [1 80])';
V(Q)=answer(1);
W(Q)=str2double(answer{2});
s=sum(W);
end
if s~=1
fprintf('Weights do not add up to 1. Try Again!\n');
Group_Function2(Q2);
end
end
Group_Function3 (Where the problem occurs)
function [H] = Group_Function3(V)
prompt = {V};
title = ['Variable Ratings For' Group_Function1(answer{1})];
h = inputdlg(prompt, title, [1 80])';
end
The Problem
For 'Group_Function3' I want the prompt to include the users inputs from 'Group_Function1' so that when the prompt comes up to input the answers I know which vehicle I am entering for.
Each function runs in its own workspace, it means it does not know the state or content of variables outside of it. If you want a function to know something specific (like the name of a car), you have to give that to the function in the input parameters. A function can have several inputs parameters, you are not limited to only one.
Before going into the Group_Function3 , I'd like to propose a new way for Group_Function1.
Group_Function1 :
You run a loop to ask independantly for each car name. It is rather tedious to have to validate each dialog boxe. Here is a way to ask for the 4 car names in one go:
replace the beginning of your script with:
title1 = 'Cars';
prompt1 = {'How Many Cars (4): '};
answer1 = inputdlg(prompt1, title1 );
nCars = str2double( answer1{1} );
CarNames = getCarNames(nCars) ; % <= use this function
% [N] = Group_Function1(Q1); % instead of this one
and replace Group_Function1 with:
function CarNames = getCarNames(nCars)
title = 'Car Names';
prompt = cellstr( [repmat('Name of car #',nCars,1) , sprintf('%d',(1:nCars)).'] ) ;
CarNames = inputdlg( prompt, title, [1 80] ) ;
end
Now CarNames is a cell array containing the name of your 4 cars (as your variable N was doing earlier. I recommend sligthly more explicit variable names).
You can run the rest of your code as is (just replace N with CarNames, and Q1 with nCars).
Group_Function3 :
when you get to the Group_Function3, you have to send the current car name to the function (so it can use the name in the title or prompt). So replace your Group_Function3 as following (we add an input variable to the function definition):
function H = Group_Function3( V , thisCarName )
prompt = {V};
title = ['Variable Ratings For' thisCarName];
H = inputdlg(prompt, title, [1 80])';
end
and in your main script, call it that way:
for h = 1:nCars
thisCarName = carNames{h} ;
H = Group_Function3( V , thisCarName ) ;
% ...
% anything else you want to do in this loop
end

How to combine ranges in VBA?

I have a form that I have developed in Excel and added a command button to print the form. There are four pages to the form, but if the first cell of the second or third pages of the cell are blank, I want to skip those pages. I have come up with the following code, but i get an "Type Mismatch" error as it combines the ranges. Is this not an appropriate way to combine ranges/ is there a better way?
Private Sub PrintAuth1_Click()
' Prints the Authorization Form upon clicking once
Dim printrng As Range 'Range to be printed so that blank pages are not printed.
Set printrng = Worksheets("BLR 13210").Range("A1:AX69")
Dim ws As Worksheet
Set ws = ActiveSheet
If ws.Range("E75") <> "" Then 'If first line of this page is blank, then it won't print the page
printrng = printrng & ws.Range("A70:AX135")
End If
If ws.Range("E141") <> "" Then 'If first line of this page is blank, then it won't print the page
printrng = printrng & ws.Range("A136:AX200")
End If
printrng = printrng & ws.Range("A201:AX264") 'Adds last page to print range
' Dialog Box to decide whether to quick print or make changes to printer setup.
msg = "Would you like to send to default printer?"
msg = msg & vbNewLine
config = vbYesNoCancel + vbQuestion + vbDefaultButton1
Title = "Printer Selection"
ans = MsgBox(msg, config, Title)
If ans = vbYes Then printrng.PrintOut Copies:=1, Collate:=True
If ans = vbNo Then Application.Dialogs(xlDialogPrint).Show
If ans = vbCancel Then
End If
End Sub

Why isnt this matlab code working?

I'm trying to write a script to remove comment lines from another script file. Here's what I tried:
fid = fopen('correct_answer.m');
aline = {};
counter = 1;
while ~feof(fid)
aline{counter} = fgetl(fid);
if aline{counter}(1) == '%'
aline{counter} = '';
end
counter = counter + 1;
end
This is the error I get:
Attempted to access aline.%cell(1); index out of bounds because numel(aline.%cell)=0.
Error in hw2 (line 8)
if aline{counter}(1) == '%'
If I run it without the while loop it works fine. What's up with this??
Also if you just happen to know a more simple/efficient approach to removing comment lines that would work too ;)
The problem is that you sometimes read empty lines, and you cannot access the first element of empty lines. Additionally you may have comments at the end of a valid line of code, this code should do the trick
fid = fopen('correct_answer.m');
aline = {};
counter = 1;
while ~feof(fid)
aline{counter} = fgetl(fid);
if ~isempty(aline{counter})
k = strfind(aline{counter}, '%');
aline{counter}(k:end) = '';
end
counter = counter + 1;
end

Error while trying to open files in Matlab

My code has 2 parts. First part is an automatic file opening programmed like this :
fichierref = 'H:\MATLAB\Archive_08112012';
files = dir(fullfile(fichierref, '*.txt'));
numberOfFiles = numel(files);
delimiterIn = ' ';
headerlinesIn = 11;
for d = 1:numberOfFiles
filenames(d) = cellstr(files(d).name);
end
for i=1:numberOfFiles
data = importdata(fullfile(fichierref,filenames{i}),delimiterIn,headerlinesIn);
end
Later on, I want the user to select his files for analysis. There's a problem with this though. I typed the lines as follow :
reference = warndlg('Choose the files from which you want to know the magnetic field');
uiwait(reference);
filenames = cellstr(uigetfile('./*.txt','MultiSelect', 'on'));
numberOfFiles = numel(filenames);
delimiterIn = ' ';
headerlinesIn = 11;
It's giving me the following error, after I press OK on the prompt:
Error using cellstr (line 34)
Input must be a string.
Error in FreqVSChampB_no_spec (line 128)
filenames = cellstr(uigetfile('./*.txt','MultiSelect', 'on'));
Anyone has an idea why it's doing that?
You do not need the cellstr command for the output of uigetfile in 'MultiSelect' mode: the output is already in a cellarray form (see doc of uigetfile).

MatLab: Error handling of integer input

How do I in MatLab catch the error that occours when the user enters letters and other things that aren't numbers in the input:
width = input('Enter a width: ');
I have played around for a while with the try/catch command:
width = 0;
message = '';
% Prompting.
while strcmp(message,'Invalid.') || width < 1 || width ~= int32(width)
try
disp(message)
width = input('Frame width: ');
catch error
message = 'Invalid.';
end
end
But with no luck (the above doesn't work). As shown I would like a simple message like "Frame width: " for the user the first time he has to enter his choice. But if an error is caught I want the message for him to be "Invalid. Try again: " fx everytime an error occours.
I have also tried the error() but I don't know how to place that correctly. Since the error() doesn't take the input command, where the error happends, as an argument, it must detect it in another way, which I can't figure.
Any help would be appreciated.
width = input('Frame width: ');
while(~isInt(width))
width = input('Invalid. Try again: ');
end
and you'll have to have the following function somewhere (or another implementation of it)
function retval = isInt(val)
retval = isscalar(val) && isnumeric(val) && isreal(val) && isfinite(val) && (val == fix(val));
end
answer = input('Frame width: ', 's');
[width, status] = str2num(answer);
while ~status || ~isscalar(width) || width ~= floor(width)
answer = input('Invalid. Try again: ', 's');
[width, status] = str2num(answer);
end
disp(width);
(status is 0 if the conversion failed. Without the isscalar test, an input like [1 2; 3 4] would also be accepted. The last test ensures that width must be an integer.)