Function overwrites output with a different number
3 views (last 30 days)
Show older comments
Claudius Simon Appel
on 22 Mar 2020
Commented: Claudius Simon Appel
on 26 Mar 2020
Hello,
This function is outputting a variable called LPfittypeindx that is used to navigate inside the fitting function. Every single fittype is referred to by this. My problem is that for some reason, it first does assign the correct number, but then immediately overwrites it with the casenumber of the specific list. For example, if you choose Fourier --> Fourier 7, it will assign assign LPfittypeindx=7, instead of retaining the 18 as it should. This happens for all options. I have zero clue why this happens, as there is exactly one instance in there that assigns 1 to the indx, that being if you choose poly1. What am I missing?
Below is the function, which is called with LPfittypeindx=LPFitlistfun:
function [LPFitindx,LPFitindxGeneral,LPFitlist,LPFitlistGeneral,LPtf1,LPtf2,LPfittypeindx] = LPFitlistfun
%UNTITLED2 Summary of this function goes here
% Detailed explanation goes here
LPFitlistGeneral={'PolyX','ExponentialX','FourierX','GaußianX','PowerX','RationalX_X','Weibull','InterpolantX','Sum of SineX','Custom_not_working'};
[LPFitindxGeneral,LPtf1]=listdlg('ListString',LPFitlistGeneral,'PromptString','Select Degree','Name','PolyX','SelectionMode','single','ListSize',[160 145])
switch LPFitindxGeneral
case 1 %PolyX
LPFitlist={'Poly1','Poly2','Poly3','Poly4','Poly5','Poly6','Poly7','Poly8','Poly9'};
[LPFitindx, LPtf2]=listdlg('ListString',LPFitlist,'PromptString','Select Fittype','Name','Fittype-Selection','SelectionMode','Single','ListSize',[160 130]);
switch LPFitindx
case 1
LPfittypeindx=1
case 2
LPfittypeindx=2
case 3
LPfittypeindx=3
case 4
LPfittypeindx=4
case 5
LPfittypeindx=5
case 6
LPfittypeindx=6
case 7
LPfittypeindx=7
case 8
LPfittypeindx=8
case 9
LPfittypeindx=9
end
case 2 %ExponentialX
LPFitlist={'Exponential_1','Exponential_2'};
[LPFitindx, LPtf2]=listdlg('ListString',LPFitlist,'PromptString','Select Fittype','Name','Fittype-Selection','SelectionMode','Single','ListSize',[160 130])
switch LPFitindx
case 1
LPfittypeindx=10
case 2
LPfittypeindx=11
end
case 3 %FourierX
LPFitlist={'Fourier1','Fourier2','Fourier3','Fourier4','Fourier5','Fourier6','Fourier7','Fourier8'};
[LPFitindx, LPtf2]=listdlg('ListString',LPFitlist,'PromptString','Select Fittype','Name','Fittype-Selection','SelectionMode','Single','ListSize',[160 130])
switch LPFitindx
case 1
LPfittypeindx=12
case 2
LPfittypeindx=13
case 3
LPfittypeindx=14
case 4
LPfittypeindx=15
case 5
LPfittypeindx=16
case 6
LPfittypeindx=17
case 7
LPfittypeindx=18
case 8
LPfittypeindx=19
end
case 4 %GaussianX
LPFitlist={'Gaussian1','Gaussian2','Gaussian3','Gaussian4','Gaussian5','Gaussian6','Gaussian7','Gaussian8'};
[LPFitindx, LPtf2]=listdlg('ListString',LPFitlist,'PromptString','Select Fittype','Name','Fittype-Selection','SelectionMode','Single','ListSize',[160 130])
switch LPFitindx
case 1
LPfittypeindx=20
case 2
LPfittypeindx=21
case 3
LPfittypeindx=22
case 4
LPfittypeindx=23
case 5
LPfittypeindx=24
case 6
LPfittypeindx=25
case 7
LPfittypeindx=26
case 8
LPfittypeindx=27
end
case 5 %PowerX
LPFitlist={'Power1','Power2'};
[LPFitindx, LPtf2]=listdlg('ListString',LPFitlist,'PromptString','Select Fittype','Name','Fittype-Selection','SelectionMode','Single','ListSize',[160 130])
switch LPFitindx
case 1
LPfittypeindx=28
case 2
LPfittypeindx=29
end
case 6 %RationalX_X
LPFitlist={'0','1','2','3','4','5'};
[LPFitindx, LPtf2]=listdlg('ListString',LPFitlist,'PromptString','Select Numerator Degree','Name','Rational Numerator','SelectionMode','Single','ListSize',[160 130])
switch LPFitindx
case 1 %0
Denominatorlist={'1','2','3','4','5'};
[Denominatorindx, tf3]=listdlg('ListString',Denominatorlist,'PromptString','Select Denominator Degree','Name','Rational Denominator','SelectionMode','Single','Listsize',[160 130])
answer=questdlg('"You`re still here?"')
clear answer
switch Denominatorindx
case 1
LPfittypeindx=30
case 2
LPfittypeindx=31
case 3
LPfittypeindx=32
case 4
LPfittypeindx=33
case 5
LPfittypeindx=34
end
case 2 %1
Denominatorlist={'1','2','3','4','5'};
[Denominatorindx, tf3]=listdlg('ListString',Denominatorlist,'PromptString','Select Denominator Degree','Name','Rational Denominator','SelectionMode','Single','Listsize',[160 130])
answer=questdlg('"A feeling of dread hangs over you... But you stay determined."')
clear answer
switch Denominatorindx
case 1
LPfittypeindx=35
case 2
LPfittypeindx=36
case 3
LPfittypeindx=37
case 4
LPfittypeindx=38
case 5
LPfittypeindx=39
end
case 3 %2
Denominatorlist={'1','2','3','4','5'};
[Denominatorindx, tf3]=listdlg('ListString',Denominatorlist,'PromptString','Select Denominator Degree','Name','Rational Denominator','SelectionMode','Single','Listsize',[160 130])
answer=questdlg('"The waterfall here seems to flow from the ceiling of the cavern.Occasionally, a piece of trash will flow through and fall into the bottomless abyss below. Viewing this endless cycle of worthless garbage. It fills you with determination."')
clear answer
switch Denominatorindx
case 1
LPfittypeindx=40
case 2
LPfittypeindx=41
case 3
LPfittypeindx=42
clear answer
answertoallquestions=questdlg('Is this the answer to all questions?','42');
switch answertoallquestions
case 'Yes'
disp('I see...')
clear answertoallquestions
disp('You have chosen ......')
disp('wisely')
pause(10)
case 'No'
clc;
clear all
close all
disp('wrong answer.')
case 'Cancel'
clc;
close all
answertoallquestions2=questdlg('Are you sure you wanna cancel? I''d rather agree if I''d be you','Is it the answer?')
switch answertoallquestions2
case 'Yes'
clear all
case 'No'
disp('...wise decision')
case 'Cancel'
disp('...wise decision')
end
end
case 4
LPfittypeindx=43
case 5
LPfittypeindx=44
end
case 4 %3
Denominatorlist={'1','2','3','4','5'};
[Denominatorindx, tf3]=listdlg('ListString',Denominatorlist,'PromptString','Select Denominator Degree','Name','Rational Denominator','SelectionMode','Single','Listsize',[160 130])
answer=questdlg('"Partaking in useless garbage fills you with determination."')
clear answer
switch Denominatorindx
case 1
LPfittypeindx=45
case 2
LPfittypeindx=36
case 3
LPfittypeindx=47
case 4
LPfittypeindx=48
case 5
LPfittypeindx=49
end
case 5 %4
Denominatorlist={'1','2','3','4','5'};
[Denominatorindx, tf3]=listdlg('ListString',Denominatorlist,'PromptString','Select Denominator Degree','Name','Rational Denominator','SelectionMode','Single','Listsize',[160 130])
answer=questdlg('"but you didn`t get this far by giving up, did you? that`s right. you have something called `determination´. so as long as you hold on.. so long as you do what`s in your heart.. i believe you can do the right thing."')
clear answer
switch Denominatorindx
case 1
LPfittypeindx=50
case 2
LPfittypeindx=51
case 3
LPfittypeindx=52
case 4
LPfittypeindx=53
case 5
LPfittypeindx=54
end
case 6 %5
Denominatorlist={'1','2','3','4','5'};
[Denominatorindx, tf3]=listdlg('ListString',Denominatorlist,'PromptString','Select Denominator Degree','Name','Rational Denominator','SelectionMode','Single','Listsize',[160 130])
answer=questdlg('"on days like these, kids like you... should be burning in hell."')
clear answer
switch Denominatorindx
case 1
LPfittypeindx=55
case 2
LPfittypeindx=56
case 3
LPfittypeindx=57
case 4
LPfittypeindx=58
case 5
LPfittypeindx=59
end
end
case 7 %Weibull
LPFitlist={'Weibull'};
[LPFitindx, LPtf2]=listdlg('ListString',LPFitlist,'PromptString','Select Fittype','Name','Fittype-Selection','SelectionMode','Single','ListSize',[160 50])
LPfittypeindx=60
case 8 %Interpolant
LPFitlist={'Nearest Neighbor','Linear','Cupic','Shape-Preserving (PCHIP)'};
[LPFitindx, LPtf2]=listdlg('ListString',LPFitlist,'PromptString','Select Fittype','Name','Fittype-Selection','SelectionMode','Single','ListSize',[160 60])
switch LPFitindx
case 1
LPfittypeindx=61
case 2
LPfittypeindx=62
case 3
LPfittypeindx=63
case 4
LPfittypeindx=64
end
case 9 %SumofSineX
LPFitlist={'1','2','3','4','5','6','7','8'};
[LPFitindx, LPtf2]=listdlg('ListString',LPFitlist,'PromptString','Select Number of terms','Name','NofTerms-Selection','SelectionMode','Single','ListSize',[160 118])
switch LPFitindx
case 1
LPfittypeindx=65
case 2
LPfittypeindx=66
case 3
LPfittypeindx=67
case 4
LPfittypeindx=68
case 5
LPfittypeindx=69
case 6
LPfittypeindx=70
case 7
LPfittypeindx=71
case 8
LPfittypeindx=72
end
case 10 %Custom
LPFitlist={'Simple','With fo in detailed code'};
[LPFitindx,LPtf2]=listdlg('ListString',LPFitlist,'PromptString','Select Degree of customosation','Name','Custom Fit','SelectionMode','Single','ListSize',[160 33])
answer=questdlg('Under construction. Need to find out how to create custom LPFits for_ single use, which will be deleted afterwards.')
switch LPFitindx
case 1
LPfittypeindx=73
disp ('This should be 73')
case 2
LPfittypeindx=74
end
end
end
When, for example, going for custom_not_working --> simple, it does output 73, along with the message "This should be 73" I put in, but then somehow LPfittypeindx is redefined as 1. Why does this happen?
Thank you for helping.
4 Comments
dpb
on 22 Mar 2020
OBTW...I had a refactoring suggestion as well--put that long call and return stack of variables into a struct and pass it in/out instead.
Accepted Answer
dpb
on 22 Mar 2020
Edited: dpb
on 22 Mar 2020
Besides the refactoring and code mlint suggestions removal, I think the biggest problem is the function definition line
function [LPFitindx,LPFitindxGeneral,LPFitlist,LPFitlistGeneral,LPtf1,LPtf2,LPfittypeindx] = LPFitlistfun
returns variable LPFitindx as the first returned variable and LPfittypeindx as the last in a very long list of outputs. You define it (the latter) inside the function, but unless your calling statement has a place to assign all those outputs, everything except the first in the list will be thrown away and the first one the only one returned, and its value will be whatever is returned from listdlg.
"which is called with LPfittypeindx=LPFitlistfun:"
and so you have just assigned the value of LPFitindx from the function call to the variable LPfittypeindx in the calling function/workplace.
You've simply thrown away the value you're looking for by not having a place for it to be stored when you called the routine.
[~,~,~,~,~,~,LPfittypeindx] = LPFitlistfun;
will return the variable you're looking for instead.
Given that klunky syntax, I'd suggest rearranging the order of outputs such that the most common one(s) are listed first as default ans and the less-used towards the end.
Actually, probably the better route with so many that seemingly are all related to the user interface would be to place all of the variables as elements in an interface structure and pass the struct inself, not the individual variables.
3 Comments
More Answers (1)
Guillaume
on 24 Mar 2020
Edited: Guillaume
on 24 Mar 2020
"How would I create and store that question tree/its outputs"
There are many options, which one you'd choose would be up to you, you could store the tree in a cell array, or as a digraph (which you could navigate with predecessors and successors), or as a table, possibly in a containers.Map, etc. Similarly there are many options on what you store in your tree and how you actually create it. It requires some thinking as to what works best for your case.
Here, thinking of easy creation, the tree could be stored as a table so it can be imported directly. Each row of the table would an option. The one difficulty is differentiating leaves of the tree which terminate the navigation and sets the return value from the branches which have a title, dialog size, prompt, etc. for their successors. I'll just store them all as columns of the tables with some blank entries for the leaves and other blank entries for the branches. The nice thing is that the tree can be stored completely separately as a text file:
Node Parent IsLeaf Title Prompt Width Height ReturnValue
0 -1 0 "Main" "Select Main Fit" 160 145 0
1 0 0 "PolyX" "Selection Poly" 160 130 0
2 1 1 "Poly1" "" 0 0 1
3 1 1 "Poly2" "" 0 0 2
4 1 1 "Poly3" "" 0 0 3
5 1 1 "Poly4" "" 0 0 4
6 0 0 "ExponentialX" "Selection Exp" 160 130 0
7 6 1 "Exponent_1" "" 0 0 5
8 6 1 "Exponent_2" "" 0 0 6
9 0 0 "Option" "Select SubOption" 160 130 0
10 9 0 "SubOption1" "Select SubsubOpt" 160 130 0
11 10 1 "SubSub1" "" 0 0 7
12 10 1 "SubSub2" "" 0 0 8
13 9 1 "SubOption2" "" 0 0 9
I've amalgamated the option name and the Title of the dialog corresponding to that option under the same 'Title', that could be separate. The IsLeaf is not really necessary, it could be detected by the fact that the node is never a parent or by the ReturnValue of 0.
The above can easily be imported with:
tree = readtable('tree.txt'); %assuming it's saved as tree.txt of course
Now the function to navigate the tree could be:
function selection = TreePrompter(tree, allowbackup)
%tree: a table with variables Node, Parent, IsLeaf, Title, Prompt, Width, Height, ReturnValue
%allowbackup: optional flag (default true)
%selection: tree.ReturnValue of selected option or empty if cancelled
if nargin < 2
allowbackup = true;
end
%todo: validate inputs. May also want to check that the tree entries are consistent
%initialise navigation:
currentrow = find(tree.Node == 0);
selection = [];
%navigate the tree
while true
childrenrows = find(tree.Parent == tree.Node(currentrow)); %can't use logical array as we'll need to index into the children array
options = tree.Title(childrenrows);
if allowbackup && tree.Node(currentrow) ~= 0 %don't allow backup at root
options = [options; {'Back one level'}]; %#ok<AGROW>
end
selectedentry = listdlg('ListString', options, ...
'PromptString', tree.Prompt{currentrow}, ...
'Name', tree.Title{currentrow}, ...
'SelectionMode', 'single', ...
'ListSize', tree{currentrow, {'Width', 'Height'}});
if isempty(selectedentry)
return; %user cancelled
end
if selectedentry > numel(childrenrows) %can only be back up
currentrow = find(tree.Node == tree.Parent(currentrow)); %go back to parent
else
currentrow = childrenrows(selectedentry);
if tree.IsLeaf(currentrow) %navigation completed
selection = tree.ReturnValue(currentrow);
return;
end
end
end
end
The nice thing about this is that you can change the tree without having to change the code at all, or you can completely replace the UI without needing to touch the tree.
5 Comments
See Also
Categories
Find more on Logical in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!