While loop not working

2 views (last 30 days)
Harrison Forlines on 30 Nov 2021
Edited: DGM on 30 Nov 2021
I'm trying to get the use input from a menu function to use as parameterts in the if statements and fo rthe most part it works. Unfortunately, the only output in the function from the if statemtns seems to be the one for PF instead of any of the other ones. For example if i were to use select the second option from the menu, the if statement for P == 1 executes. Does anyone know how to fix this?
clear;clc;
P = menu('Select Given Values: ','PF','Pact & Pre','Pact & Papp','Pre & Papp');
while P == 0 || isempty(P)
P = menu('Select Given Values: ','PF','Pact & Pre','Pact & Papp','Pre & Papp')
disp('Error, must input valid combo!')
end
if P == 1
else
PF = input('Input value of power factor (PF), or press enter if N/A: ');
end
if P == 2
else
Pact = input('Input value of active/real power (Pact), or press enter if N/A: ');
Pre = input('Input value of reactive power (Pre), or press enter if N/A: ');
end
if P == 3
else
Pact = input('Input value of active/real power (Pact), or press enter if N/A: ');
Papp = input('Input value of apparent power (Papp), or press enter if N/A: ');
end
if P == 4
else
Pre = input('Input value of reactive power (Pre), or press enter if N/A: ');
Papp = input('Input value of apparent power (Papp), or press enter if N/A: ');
end

DGM on 30 Nov 2021
Edited: DGM on 30 Nov 2021
Your if statements don't do anything when they test true. That should all be one if-elseif structure because the cases are all mutually exclusive. Since the tests are all scalar, you could just use a switch-case structure.
P = menu('Select Given Values: ','PF','Pact & Pre','Pact & Papp','Pre & Papp');
while P == 0 || isempty(P)
P = menu('Select Given Values: ','PF','Pact & Pre','Pact & Papp','Pre & Papp')
disp('Error, must input valid combo!')
end
switch P
case 1
PF = input('Input value of power factor (PF), or press enter if N/A: ');
case 2
Pact = input('Input value of active/real power (Pact), or press enter if N/A: ');
Pre = input('Input value of reactive power (Pre), or press enter if N/A: ');
case 3
Pact = input('Input value of active/real power (Pact), or press enter if N/A: ');
Papp = input('Input value of apparent power (Papp), or press enter if N/A: ');
case 4
Pre = input('Input value of reactive power (Pre), or press enter if N/A: ');
Papp = input('Input value of apparent power (Papp), or press enter if N/A: ');
end
Alternatively, you could use the menu to specify the number of inputs and then use inputdlg() to prompt for the specific inputs.
I'm of the opinion that interactively prompting the user for inputs is a great way to make your interface unnecessarily tedious and frustrating to use. If you really want to do it interactively, you could do as much of it at once as possible.
Instead of having the user tell the computer what to ask for, just ask the user to enter whatever parameters they choose to enter and then act according to what they entered. The following is a crude dialog that has four text entry fields. The user is prompted to enter any two parameters. Once two parameters have been entered, the dialog automatically closes and the function returns a cell array containing the parameters. Based on which elements of the cell array are non-empty, you could calculate all the others as needed.
function inputvalues = powerdialogthing()
% open a dialog prompting the user for two of four boxes to be filled.
% exit once two boxes have been filled.
inputvalues = cell(4,1);
h1 = figure(...
'Units','normalized',...
'Name','Prameters',...
'NumberTitle','off',...
'Position',[0.35 0.57 0.13 0.25]);
eh = 0.075; % element height
tsp = 0.9; % start height (1 - top margin)
hm = 0.1; % left/right margin
hem = 0.05; % horiz element margin
bw = 0.3; % box width
tw = 1-2*hm-hem-bw; % text width
bxos = hm+tw+hem; % box offset
vos = 2*eh; % vertical line spacing
basetextprops = {'Parent',h1,...
'Units','normalized',...
'FontSize',10,...
'HorizontalAlignment','left',...
'Style','text'};
baseboxprops = {'Parent',h1,...
'Units','normalized',...
'BackgroundColor',[1 1 1],...
'HorizontalAlignment','left',...
'String',[],...
'Style','edit'};
% power factor
uicontrol(basetextprops{:},...
'Position',[hm tsp-0.01-eh tw eh],...
'String','Power Factor',...
'Tag','pfboxlabel');
uicontrol(baseboxprops{:},...
'Position',[bxos tsp-eh bw eh],...
'Tag','pfbox',...
'callback',{@setparam,1});
% real power
uicontrol(basetextprops{:},...
'Position',[hm tsp-0.01-eh-vos tw eh],...
'String','Real Power',...
'Tag','prealboxlabel');
uicontrol(baseboxprops{:},...
'Position',[bxos tsp-eh-vos bw eh],...
'Tag','prealbox',...
'callback',{@setparam,2});
% imag power
uicontrol(basetextprops{:},...
'Position',[hm tsp-0.01-eh-2*vos tw eh],...
'String','Reactive Power',...
'Tag','preactboxlabel');
uicontrol(baseboxprops{:},...
'Position',[bxos tsp-eh-2*vos bw eh],...
'Tag','preactbox',...
'callback',{@setparam,3});
% power magnitude
uicontrol(basetextprops{:},...
'Position',[hm tsp-0.01-eh-3*vos tw eh],...
'String','Apparent Power',...
'Tag','pappboxlabel');
uicontrol(baseboxprops{:},...
'Position',[bxos tsp-eh-3*vos bw eh],...
'Tag','pappbox',...
'callback',{@setparam,4});
uicontrol('Parent',h1,...
'Units','normalized',...
'FontSize',14,...
'HorizontalAlignment','center',...
'Style','text',...
'Position',[hm tsp-0.01-eh-4.5*vos 1-2*hm eh],...
'String','Specify any two',...
'Tag','instructions');
waitfor(h1);
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function setparam(objh,~,param)
inputvalues{param} = str2double(get(objh,'string'));
if nnz(~cellfun(@isempty,inputvalues))>1
delete(h1); % exit once two values have been provided
end
end
end %% END OF MAIN SCOPE
As I mentioned, you can just get any two of the four inputs and then calculate everything from that, regardless of which ones are entered.
P = powerdialogthing(); % prompt the user
hasvalue = ~cellfun(@isempty,P);
% find PF
if ~hasvalue(1)
if all(hasvalue(2:4) == [1 1 0])
PF = cos(atan(P{3}/P{2}));
elseif all(hasvalue(2:4) == [1 0 1])
PF = P{2}/P{4};
elseif all(hasvalue(2:4) == [0 1 1])
PF = cos(asin(P{3}/P{4}));
end
else
PF = P{1};
end
% find Preal
if ~hasvalue(2)
if all(hasvalue([1 3 4]) == [1 1 0])
Preal = (P{3}*P{1})/sqrt(1-P{1}^2);
elseif all(hasvalue([1 3 4]) == [1 0 1])
Preal = P{1}*P{4};
elseif all(hasvalue([1 3 4]) == [0 1 1])
Preal = sqrt(P{4}^2-P{3}^2);
end
else
Preal = P{2};
end
% find Preact
if ~hasvalue(3)
if all(hasvalue([1 2 4]) == [1 1 0])
Preact = (P{2}*sqrt(1-P{1}^2))/P{1};
elseif all(hasvalue([1 2 4]) == [1 0 1])
Preact = sqrt((1-P{1}^2)/P{4}^2);
elseif all(hasvalue([1 2 4]) == [0 1 1])
Preact = sqrt(P{4}^2-P{2}^2);
end
else
Preact = P{3};
end
% find Papp
if ~hasvalue(4)
if all(hasvalue(1:3) == [1 1 0])
Papp = P{2}/P{1};
elseif all(hasvalue(1:3) == [1 0 1])
Papp = P{3}/sqrt(1-P{1}^2);
elseif all(hasvalue(1:3) == [0 1 1])
Papp = sqrt(P{2}^2+P{3}^2);
end
else
Papp = P{4};
end
% everything
PF
Preal
Preact
Papp
I'm sure that could be simplified yet, but eh. You'll probably want to doublecheck my math. I might've missed something.

R2021a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!