How do you run a script with a button in a function?

I have a (simplified) script called Holecheck. This script contains an important variable 'I':
if
%code
else if
%code
else
run Doesnotfit
end
end
Doesnotfit is a function looking as follows:
function Doesnotfit
I=evalin('base','I');
%stop=evalin('base','stop');
% I = 0;
%fgh = figure('position',[1100,30,210,60]);
uicontrol('Parent',figure(2), 'Style', 'Pushbutton', 'String', 'Go left',...
'Position',[0.1,0.1,50,20], 'Callback', @Ileft);
uicontrol('Parent',figure(2), 'Style', 'Pushbutton', 'String', 'Go right',...
'Position',[100,0.1,50,20], 'Callback', @Iright);
uicontrol('Parent',figure(2), 'Style', 'Pushbutton', 'String', 'Accept',...
'Position',[50,0.1,50,20], 'Callback', @Iaccept);
mTextBox = uicontrol('Parent',figure(2),'style','text');
set(mTextBox,'String',num2str(I))
function Ileft(~,~)
I=I-1
assignin('base', 'I', I)
set(mTextBox,'String',num2str(I))
end
function Iright(~,~)
I=I+1
assignin('base', 'I', I)
set(mTextBox,'String',num2str(I))
end
function Iaccept(~,~)
Holecheck
end
end
In short, there are three buttons and a text. The first two buttons add 1 or -1 to variable 'I'. When last button (Iaccept) is pressed, the script should automatically run the starting file 'Holecheck' again from the start. However, I get the following error:
Attempt to add "Xout" to a static workspace. See Variables in Nested and Anonymous Functions.
Error in Holecheck (line 2) Xout=500;
Error in Doesnotfit/Iaccept (line 31) Holecheck
Error while evaluating UIControl Callback
I have already read something about 'Variables in Nested and Anonymous Functions' but i still don't understand.
Please can you help me? Thanks

3 Comments

Adam
Adam on 25 Jul 2017
Edited: Adam on 25 Jul 2017
Why is Holecheck a script rather than a function? Also it would be so much simpler if you just pass variables around as arguments to functions rather than using evalin and assignin. Functions each have their own workspace into which you can pass arguments and return them rather than trying to keep forcing them in and out of the base workspace which shouldn't be involved at all.
You get the error because, as a script, Holecheck (whose troublesome line you haven't included in the above code anyway) will just dump all its variables into the calling workspace, except you cannot do that because the workspace is static because it contains nested functions therefore variables cannot be added to it. If it were a function then it wouldn't have this problem unless you return arguments from it and in that scenario it could be worked around by pre-declaring the variable in question I would imagine.
Thanks for your answer. However, as you might have seen, i'm not very experienced with Matlab.
With the holecheck code, every run i update 7 different matrices. These matrices contain rectangles dimension for a number of different subplots. Then after each update these rectangles are plot and it is checked whether they all fit. (see picture)
Do you think it is easy to convert this script into a funtion? And what steps are then necessary? This is my Holecheck code:
function Holecheck(I)
%define rectangle for plot
Xout=500;
Yout=500;
r=100;
Edge=r-cosd(45)*r;
X=Xout-2*Edge;
Y=Yout-2*Edge;
%make plot
HY=3;
HX=6;
n=1;
figHandle = figure(2);
hold on
for k=0:HY-1
Hole(n)=k*(HX+2)+1;
subplot(HY+1,HX+2,Hole(n));
axis([-Edge Xout+Edge -Edge Yout+Edge])
rectangle('Position',[0 0 X Y])
rectangle('Position',[-Edge -Edge Xout Yout],'Curvature',[(2*r/X) (2*r/Y)])
title(['Hole ' num2str(n)])
n=n+1;
end
for k=(HY*(HX+2))+2:((HY+1)*(HX+2))-1
Hole(n)=k;
subplot(HY+1,HX+2,k);
axis([-Edge Xout+Edge -Edge Yout+Edge])
rectangle('Position',[0 0 X Y])
rectangle('Position',[-Edge -Edge Xout Yout],'Curvature',[(2*r/X) (2*r/Y)])
title(['Hole ' num2str(n)])
n=n+1;
end
for k=HY:-1:1
Hole(n)=k*(HX+2);
subplot(HY+1,HX+2,Hole(n));
axis([-Edge Xout+Edge -Edge Yout+Edge])
rectangle('Position',[0 0 X Y])
rectangle('Position',[-Edge -Edge Xout Yout],'Curvature',[(2*r/X) (2*r/Y)])
title(['Hole ' num2str(n)])
n=n+1;
end
sheet=1;
Range1='A19:B19';Range2='C19:D19';Range3='E19:F19';Range4='G19:H19';Range5='I19:J19';Range6='K19:L19';Range7='M19:N19';
%fill matrices
Cable{I}=[Cable{I}(1:end-1,:);xlsread(filename,sheet,Range1);0 0];
Grey{I}=[Grey{I}(1:end-1,:);xlsread(filename,sheet,Range2);0 0];
Black{I}=[Black{I}(1:end-1,:);xlsread(filename,sheet,Range3);0 0];
HVACS{I}=[HVACS{I}(1:end-1,:);xlsread(filename,sheet,Range4);0 0];
HVACE{I}=[HVACE{I}(1:end-1,:);xlsread(filename,sheet,Range5);0 0];
HVACR{I}=[HVACR{I}(1:end-1,:);xlsread(filename,sheet,Range6);0 0];
POT{I}=[POT{I}(1:end-1,:);xlsread(filename,sheet,Range7);0 0];
A=rectangle('Position',[0 Y-Cable{I}(1,2) 0 0]);
B=rectangle('Position',[0 0 0 0]);
%%Plotting all defined rectangles in figure.
%%Cable ladders
figure(figHandle);
subplot(HY+1,HX+2,Hole(I));
XC(1,1)=0;
YC(1,1)=Y-Cable{I}(1,2);
if any(Cable{I}>0)
for i=1:size(Cable{I},1)-1
if Cable{I}(i,1)<=X
if Cable{I}(i,2)<=Y
if Cable{I}(i,1)<=(X-XC(i,1))
A=rectangle('Position',[XC(i,1) YC(i,1) Cable{I}(i,1) Cable{I}(i,2)],'FaceColor','Blue');
XC(i+1,1)=XC(i,1)+Cable{I}(i,1);
YC(i+1,1)=YC(i,1)-(Cable{I}(i,2)-Cable{I}(i+1,2));
elseif Cable{I}(i,2)<=min(YC(1:i,1))
XC(i,1)=0;
YC(i,1)=min(YC(1:i-1,1))-Cable{I}(i,2);
A=rectangle('Position',[XC(i,1) YC(i,1) Cable{I}(i,1) Cable{I}(i,2)],'FaceColor','Blue');
XC(i+1,1)=XC(i,1)+Cable{I}(i,1);
YC(i+1,1)=YC(i,1)+(Cable{I}(i,2)-Cable{I}(i+1,2));
else
disp(['Does not fit for hole ' num2str(I)])
Cable{I}(end-1,:)=[]
I=I+1
run Holecheck
break
end
end
else disp(['Does not fit for hole ' num2str(I)])
end
end
YC(end,:)=[];
end
%%Grey water lines
figure(figHandle);
subplot(HY+1,HX+2,Hole(I));
XG=0;
YG=0;
HPG=0;
for i=1:size(Grey{I},1)-1
if Grey{I}(i,1)<=X
if Grey{I}(i,2)<=Y
if Grey{I}(i,1)<=(X-XG(i,1))
B=rectangle('Position',[XG(i,1) YG(i,1) Grey{I}(i,1) Grey{I}(i,2)],'FaceColor',[0.38 0.20 0.07]);
XG(i+1,1)=XG(i,1)+Grey{I}(i,1);
YG(i+1,1)=YG(i,1);
HPG(i,1)=YG(i,1)+Grey{I}(i,2);
elseif Grey{I}(i,2)<=min(YC)-max(HPG(1:end-1,1))
XG(i,1)=0;
YG(i,1)=max(HPG(1:end-1,1));
B=rectangle('Position',[XG(i,1) YG(i,1) Grey{I}(i,1) Grey{I}(i,2)],'FaceColor',[0.38 0.20 0.07]);
XG(i+1,1)=XG(i,1)+Grey{I}(i,1);
YG(i+1,1)=YG(i,1);
HPG(i,1)=YG(i,1)+Grey{I}(i,2);
else
Grey{I}(end-1,:)=[]
Doesnotfit
break
end
end
else disp(['Does not fit for hole ' num2str(I)])
end
end
%%Black water lines
figure(figHandle);
subplot(HY+1,HX+2,Hole(I));
XB=0+XG(end,1);
YB=0+YG(end,1);
HPB=0+max(HPG);
for i=1:size(Black{I},1)-1
if Black{I}(i,1)<=X
if Black{I}(i,2)<=Y
if Black{I}(i,1)<=(X-XB(i,1))
B=rectangle('Position',[XB(i,1) YB(i,1) Black{I}(i,1) Black{I}(i,2)],'FaceColor','Black');
XB(i+1,1)=XB(i,1)+Black{I}(i,1);
YB(i+1,1)=YB(i,1);
HPB(end+1,1)=YB(i,1)+Black{I}(i,2);
elseif Black{I}(i,2)<=min(YC)-max(HPB)
XB(i,1)=0;
YB(i,1)=max(HPB);
B=rectangle('Position',[XB(i,1) YB(i,1) Black{I}(i,1) Black{I}(i,2)],'FaceColor','Black');
XB(i+1,1)=XB(i,1)+Black{I}(i,1);
YB(i+1,1)=YB(i,1);
HPB(end+1,1)=YB(i,1)+Black{I}(i,2);
else
disp(['Does not fit for hole ' num2str(I)])
Black{I}(end-1,:)=[]
I=I+1
run Holecheck
break
end
end
else disp(['Does not fit for hole ' num2str(I)])
end
end
%%HVAC supply
figure(figHandle);
subplot(HY+1,HX+2,Hole(I));
XHS=0+XB(end,1);
YHS=0+YB(end,1);
HPHS=0+max(max(HPG),max(HPB));
for i=1:size(HVACS{I},1)-1
if HVACS{I}(i,1)<=X
if HVACS{I}(i,2)<=Y
if HVACS{I}(i,1)<=(X-XHS(i,1))
B=rectangle('Position',[XHS(i,1) YHS(i,1) HVACS{I}(i,1) HVACS{I}(i,2)],'FaceColor',[0.80 0.60 0.80]);
XHS(i+1,1)=XHS(i,1)+HVACS{I}(i,1);
YHS(i+1,1)=YHS(i,1);
HPHS(end+1,1)=YHS(i,1)+HVACS{I}(i,2);
elseif HVACS{I}(i,2)<=min(YC(:,1))-max(HPHS)
XHS(i,1)=0;
YHS(i,1)=max(HPHS);
B=rectangle('Position',[XHS(i,1) YHS(i,1) HVACS{I}(i,1) HVACS{I}(i,2)],'FaceColor',[0.80 0.60 0.80]);
XHS(i+1,1)=XHS(i,1)+HVACS{I}(i,1);
YHS(i+1,1)=YHS(i,1);
HPHS(end+1,1)=YHS(i,1)+HVACS{I}(i,2);
else
disp(['Does not fit for hole ' num2str(I)])
HVACS{I}(end-1,:)=[]
I=I+1
run Holecheck
break
end
end
else disp(['Does not fit for hole ' num2str(I)])
end
end
%%HVAC exhaust
figure(figHandle);
subplot(HY+1,HX+2,Hole(I));
XHE=0+XHS(end,1);
YHE=0+YHS(end,1);
HPHE=0+max(max(max(HPG),max(HPB)),max(HPHS));
for i=1:size(HVACE{I},1)-1
if HVACE{I}(i,1)<=X
if HVACE{I}(i,2)<=Y
if HVACE{I}(i,1)<=(X-XHE(i,1))
B=rectangle('Position',[XHE(i,1) YHE(i,1) HVACE{I}(i,1) HVACE{I}(i,2)],'FaceColor',[0 0.20 0]);
XHE(i+1,1)=XHE(i,1)+HVACE{I}(i,1);
YHE(i+1,1)=YHE(i,1);
HPHE(end+1,1)=YHE(i,1)+HVACE{I}(i,2);
elseif HVACE{I}(i,2)<=min(YC(:,1))-max(HPHE)
XHE(i,1)=0;
YHE(i,1)=max(HPHE);
B=rectangle('Position',[XHE(i,1) YHE(i,1) HVACE{I}(i,1) HVACE{I}(i,2)],'FaceColor',[0 0.20 0]);
XHE(i+1,1)=XHE(i,1)+HVACE{I}(i,1);
YHE(i+1,1)=YHE(i,1);
HPHE(end+1,1)=YHE(i,1)+HVACE{I}(i,2);
else
disp(['Does not fit for hole ' num2str(I)])
HVACE{I}(end-1,:)=[]
I=I+1
run Holecheck
break
end
end
else disp(['Does not fit for hole ' num2str(I)])
end
end
%%HVAC recirculation
figure(figHandle);
subplot(HY+1,HX+2,Hole(I));
XHR=0+XHE(end,1);
YHR=0+YHE(end,1);
HPHR=0+max(max(max(HPG),max(HPB)),max(max(HPHS),max(HPHE)));
for i=1:size(HVACR{I},1)-1
if HVACR{I}(i,1)<=X
if HVACR{I}(i,2)<=Y
if HVACR{I}(i,1)<=(X-XHR(i,1))
B=rectangle('Position',[XHR(i,1) YHR(i,1) HVACR{I}(i,1) HVACR{I}(i,2)],'FaceColor','yellow');
XHR(i+1,1)=XHR(i,1)+HVACR{I}(i,1);
YHR(i+1,1)=YHR(i,1);
HPHR(end+1,1)=YHR(i,1)+HVACR{I}(i,2);
elseif HVACR{I}(i,2)<=min(YC(:,1))-max(HPHR)
XHR(i,1)=0;
YHR(i,1)=max(HPHR);
B=rectangle('Position',[XHR(i,1) YHR(i,1) HVACR{I}(i,1) HVACR{I}(i,2)],'FaceColor','yellow');
XHR(i+1,1)=XHR(i,1)+HVACR{I}(i,1);
YHR(i+1,1)=YHR(i,1);
HPHR(end+1,1)=YHR(i,1)+HVACR{I}(i,2);
else
disp(['Does not fit for hole ' num2str(I)])
HVACR{I}(end-1,:)=[]
I=I+1
run Holecheck
break
end
end
else disp(['Does not fit for hole ' num2str(I)])
end
end
%%Hot and cold potable water
figure(figHandle);
subplot(HY+1,HX+2,Hole(I));
XPOT=0+XHR(end,1);
YPOT=0+YHR(end,1);
HPPOT=0+max(max(max(max(HPG),max(HPB)),max(max(HPHS),max(HPHE))),max(HPHR));
for i=1:size(POT{I},1)-1
if POT{I}(i,1)<=X
if POT{I}(i,2)<=Y
if POT{I}(i,1)<=(X-XPOT(i,1))
B=rectangle('Position',[XPOT(i,1) YPOT(i,1) POT{I}(i,1) POT{I}(i,2)],'FaceColor','green');
XPOT(i+1,1)=XPOT(i,1)+POT{I}(i,1);
YPOT(i+1,1)=YPOT(i,1);
HPPOT(end+1,1)=YPOT(i,1)+POT{I}(i,2);
elseif POT{I}(i,2)<=min(YC(:,1))-max(HPPOT)
XPOT(i,1)=0;
YPOT(i,1)=max(HPPOT);
B=rectangle('Position',[XPOT(i,1) YPOT(i,1) POT{I}(i,1) POT{I}(i,2)],'FaceColor','green');
XPOT(i+1,1)=XPOT(i,1)+POT{I}(i,1);
YPOT(i+1,1)=YPOT(i,1);
HPPOT(end+1,1)=YPOT(i,1)+POT{I}(i,2);
else
disp(['Does not fit for hole ' num2str(I)])
POT{I}(end-1,:)=[]
I=I+1
run Holecheck
break
end
end
else disp(['Does not fit for hole ' num2str(I)])
end
end
%%Determine overlapping of rectangles
l = max(A.Position(1),B.Position(1));
r = min(A.Position(1)+A.Position(3),B.Position(1)+B.Position(3));
b = max(A.Position(2),A.Position(2));
t = min(A.Position(2)+A.Position(4),B.Position(2)+B.Position(4));
r3 = [l b r-l t-b];
if r3(3)>0
if r3(4)>0
disp(['Does not fit for hole ' num2str(I)])
end
end
"Do you think it is easy to convert this script into a funtion?"
Not just easy but highly recommended. For many reasons functions are just much better to work with: search this forum for the many threads that discuss this.

Sign in to comment.

Answers (0)

Categories

Commented:

on 25 Jul 2017

Community Treasure Hunt

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

Start Hunting!