msgbox in MATLAB - matlab

I want to show my output in a msgbox so I have used msgbox(num2str(output)) but I want to name each line, eg:
Red 25
Green 52
Yellow 88
but when I try to do that it says
Error using horzcat
CAT arguments dimensions are not consistent.
And when that window pops up and the user press OK then another window will pop up asking
W = questdlg('Would you like to retrain or test the network?', ...
'Artificial Neural Network', 'Retrain', 'Test', 'Exit', 'Exit');
So, how can format my msgbox and as soon as the OK button is pressed another window will popup?
Any help would be appreciated!
Thanks!

For your first question, you can use cell array notation to format your message box text:
rVal = 25;
gVal = 35;
bVal = 45;
msg = {['Red ',num2str(rVal)];...
['Green ',num2str(gVal)];...
['Blue ',num2str(bVal)]};
This allows you to vertically concatenate multi-length strings.
If your output is an Nx1 column vector, you can always format it in this manner using cellfun:
output = [25;35;45];
msgTxt = {['Red '];['Green '];['Blue ']};
msgNum = cellfun(#num2str,num2cell(output),'UniformOutput',false);
msg = cellfun(#(x,y) [x,y],msgTxt,msgNum,'UniformOutput',false);
As long as you match the msgTxt size with the output size, this should work fine for any size of the output variable.
As for making your program wait on the user response, try uiwait:
mH = msgbox(msg);
uiwait(mH)
disp('Let''s continue...')

msgbox can be formatted like this
R=23;G=35;B=45; %given values
(msgbox({['Red ',num2str(R)];['Green ',num2str(G)];['Blue ',num2str(B)]; }));
After your later part of the question
uiwait(msgbox({['Red ',num2str(R)];['Green ',num2str(G)];['Blue ',num2str(B)]; }));
W = questdlg('Would you like to retrain or test the network?', ...
'Artificial Neural Network', 'Retrain', 'Test', 'Exit', 'Exit');

Related

Is it possible to surpress that "input" jumps to the next line?

I got a code similar to this:
fprintf('Give a vector: \n')
fprintf('1. Vector/Matrix: X = {')
FirstVector = input('','s');
fprintf('}')
fprintf('\n')
It should print out something like this:
Give a vector:
1. Vector/Matrix: X = {UserInput}
Instead I get this:
Give a vector:
1. Vector/Matrix: X = {UserInput
}
The input-function is making a \n. How can I avoid that? The documentation of input is of no use, it doesn't even tell that input behaves that way.
You can get around this inherent limitation of input by adding a backspace character to the fprintf after the input. You can also condense your code into two lines, like so:
FirstVector = input('Give a vector: \n1. Vector/Matrix: X = {', 's');
fprintf([char(8) '}\n']);
Entering a 1:
Give a vector:
1. Vector/Matrix: X = {1}
Note also that the 's' option is for capturing character/string input. If you want the user to enter numeric values, leave that out.

Editing fields in matlab

I am creating message box in MATLAB with the following code
prompt={'Length'}
name = 'Input';
answer = inputdlg(prompt,name,[1 40],defaultans);
Length = str2double(answer{1});
choice = questdlg('Would you like to confirm?', ...
'Message Box', ...
'Yes','No','No');
switch choice
case 'Yes'
h = msgbox({'Operation' 'Completed'});
case 'No'
h = msgbox({'Operation' 'Failed'});
end
I am entering the value as shown in below image
After moving to next window, when i press 'No' , I want the same earlier Input window as shown above to be displayed with 120 written inside the input box so that i can change the value.
Can anyone please let me know how to switch to previous window wherein i can edit my values which have been earlier written.
Use an infinite while loop and put the inputdlg statement inside it. When the user confirms, break it.
Modified Code:
prompt={'Length'};
name = 'Input';
defaultans={'120'};
while 1
answer = inputdlg(prompt,name,[1 40],defaultans);
choice = questdlg('Would you like to confirm?', ...
'Message Box', ...
'Yes','No','No');
switch choice
case 'Yes'
h = msgbox({'Operation' 'Completed'});
Length = str2double(answer{1});
break;
end
end

MATLAB programmatic GUI listbox value and data it refers to

I am making a GUI programmatically and have run into a small question regarding the uicontrol listbox and the data each 'value' or 'string' refers to. I feel this question will best be illustrated with some code. The code at the end of this question illustrates my question.
If you run this example, select all 5 files from the left listbox and press 'Button1', you will see them go into the right listbox. You can then select 1, or several of the files in the right list box and press 'Button2' and MATLAB will output the correct files names. All is fine here.
If you close and re run the program, and just select file1, file3, and file5, pressing Button1 will make them go into the right list box again. This is where my problem is: If you select all of the files now in the right list box (file1, file3, file3), and press Button2, matlab outputs file1, file2, and file3... not file1, file3 and file5 as I would like.
Now I understand why this is happening, because in a list box its value property starts at 1 and increases, and the underlying data in the Cell DataSet remains ordered file1 to file5... So value 1 2 3 refers to DataSet{1} DataSet{2} DataSet{3}...
What would be the best way to overcome this problem? I would like to add that for my actual GUI the file names might not always be so obviously named.
classdef example < handle
properties
Figure;
Button1;
Button2;
ListBox1;
ListBox2;
DataSet = {};
end
methods
function obj = example()
create(obj);
makeUpData(obj);
end
function create(obj)
obj.Figure = figure('Position',[300 300 640 640]);
obj.Button1 = uicontrol('Style','pushbutton','String','Button1',...
'Position',[240 260 80 40],'Callback',#obj.button1CB);
obj.Button2 = uicontrol('Style','pushbutton','String','Button2',...
'Position',[510 260 80 40],'Callback',#obj.button2CB);
obj.ListBox1 = uicontrol('Style','listbox','String','',...
'Position',[50 250 145 100],'Max',3);
obj.ListBox2 = uicontrol('Style','listbox','String','',...
'Position',[350 250 145 100],'Max',3);
end
function makeUpData(obj)
obj.DataSet = {'file1' 'file2' 'file3' 'file4' 'file5'};
obj.ListBox1.String = obj.DataSet;
end
function button1CB(obj,hObject,eventdata)
CurrentNum = get(obj.ListBox1,'Value');
NameListBox1 = get(obj.ListBox1,'String');
NewName = obj.ListBox2.String;
for i = 1:numel(CurrentNum)
NewName{end+1} = [NameListBox1{CurrentNum(i)}];
end
obj.ListBox2.String = NewName;
end
function button2CB(obj,hObject,eventdata)
CurrentNum = get(obj.ListBox2,'Value')
for i = 1:numel(CurrentNum)
obj.DataSet{CurrentNum(i)}
end
end
end
end
For this application I would recommend storing your data in a structure rather than a cell array. This will allow you to utilize dynamic field references to access your data and not worry about converting from a file name to an index in your cell array.
I've modified your properties definition:
properties
Figure;
Button1;
Button2;
ListBox1;
ListBox2;
DataSet = struct;
end
Your makeUpData definition:
function makeUpData(obj)
dummydata = {'file1' 'file2' 'file3' 'file4' 'file5'};
for ii = 1:length(dummydata)
obj.DataSet.(dummydata{ii}) = dummydata{ii};
end
obj.ListBox1.String = fieldnames(obj.DataSet);
end
And your button2CB definition:
function button2CB(obj,hObject,eventdata)
listboxvalues = get(obj.ListBox2, 'String');
CurrentNum = get(obj.ListBox2,'Value');
for i = 1:numel(CurrentNum)
obj.DataSet.(listboxvalues{CurrentNum(i)})
end
end
Now your selection returns:
ans =
file1
ans =
file3
ans =
file5
As expected.
You can change callback function of Button2 as follows, using ismember to get the corresponded index in the obj.DataSet:
function button2CB(obj,hObject,eventdata)
selected = cellstr(get(obj.ListBox2, 'String'));
referred = ismember(obj.DataSet, selected);
obj.DataSet(referred)
obj.DataSet{referred}
end

Creating a translator in MatLab

I am trying to create a simple program in Matlab where the user can input a string (such as "A", "B", "AB" or "A B") and the program will output a word corresponding to my letter.
Input | Output
A Hello
B Hola
AB HelloHola
A B Hello Hola
This is my code:
A='Hello'; B='Hola';
userText = input('What is your message: ', 's');
userText = upper(userText);
for ind = 1:length(userText)
current = userText(ind);
X = ['The output is ', current];
disp(X);
end
Currently I don't get my desired results. I instead get this:
Input | Output
A The output is A
B The output is B
I'm not totally sure why X = ['The output is ', current]; evaluates to The output is A instead of The output is Hello.
Edit:
How would this program be able to handle numbers... such as 1 = "Goodbye"
What's going on:
%// intput text
userText = input('What is your message: ', 's');
%// ...and some lines later
X = ['The output is ', userText];
You never map what you type to what is contained by the variables A and B.
The fact that they are called A and B has nothing to do with what you type. You could call them C and blargh and still get the same result.
Now, you could use eval, but that's really not advisable here. In this case, using eval would force the one typing in the strings to know the exact names of your variables...that's a portability, maintainability, security, etc. disaster waiting to happen.
There are better solutions possible, for instance, create a simple map:
map = {
'A' 'Hello'
'B' 'Hola'
'1' 'Goodbye'
};
userText = input('What is your message: ', 's');
str = map{strcmpi(map(:,1), userText), 2};
disp(['The output is ', str]);
I would recommend using a map object to contain what you want. This will circumvent the eval function (which I suggest avoiding like the plague). This is pretty simple to read and understand, and is pretty efficient especially in the case of a long input string.
translation = containers.Map()
translation('A') = 'Hola';
translation('B') = 'Hello';
translation('1') = 'Goodbye';
inputString = 'ABA1BA1B11ABBA';
resultString = '';
for i = 1:length(inputString)
if translation.isKey(inputString(i))
% get mapped string if it exists
resultString = [resultString,translation(inputString(i))];
else
% if mapping does not exist, simply put the input string in (covers space case)
resultString = [resultString,inputString(i)];
end
end
Take a look at the command eval. Currently, you are displaying the name of the variable that contains the string you want. eval will help you in actually accessing and printing it.
What you need to do it :
X = ['The output is ', eval(current)];
Here the documentation : eval

How to export data from Matlab to excel for a loop?

I have a code for "for loop"
for i=1:4
statement...
y=sim(net, I);
end
now i need to export the value of y to excel sheet. for that i used..
xlswrite('output_data.xls', y, 'output_data', 'A1')
but my problem is that the ID of excel i.e. "A1" should change according to each iteration... in my case for iteration 1-> A1, iteration-> A2 and so on..
anybody please help me out ..
thanks in advance. for any assistance.. or suggestion..
You can store sim outputs in a vector (y(ii)) and save in the sheet with a single write. This is also more efficient since you perform a single bulk-write instead of many small writes.
Specify the first cell and y will be written starting from there.
last = someNumber;
for i=1:last statement... y(i)=sim(net, I); end
xlswrite('output_data.xls', y', 'output_data', 'A1');
If you prefer specify the range write ['A1:A',num2str(last)] instead of A1.
If you really want to write within the loop try:
for ii=1:last
...
y=sim(net, I);
xlswrite('output_data.xls', y, 'output_data', sprintf('A%d',ii));
end
You can also do for yourself what xlswrite does internally, which is interact using COM. I prefer to do this when I have a frequently used excel template or data file, because it allows for more control (albeit with more lines of code).
Excel = actxserver('Excel.Application');
Workbook = Excel.Workbooks.Open('myExcelFile.xlsx');
MySheet = Excel.ActiveWorkBook.Sheets.Item(1);
set( get(MySheet,'Range','A1:A10'), 'Value', yourValues);
...
invoke(Workbook, 'Save');
invoke(Excel, 'Quit');
delete(Excel);
This would allow you to save new data to new ranges without re-opening excel each time.
Even better would be to define an oncleanup function (as does xlswrite) to prevent lost file locks (especially when you're doing things like exiting out of debug mode):
...
myWorkbook = Excel.Workbooks.Open(filename,0,true);
cleanUp = onCleanup(#()xlsCleanup(Excel, filename));
function xlsCleanup(Excel,filepath)
try
Excel.DisplayAlerts = 0; %// Turn off dialog boxes
[~,n,e] = fileparts(filepath); %// Excel API expects just the filename
fileName = [n,e];
Excel.Workbooks.Item(fileName).Close(false);
end
Excel.Quit;
end
You can put xlswrite after for loop.You just want to do is save you result in a matrix.This function can write a matrix.
also,you can use [] to combine string to change the range.
>> for i=1:4
Range=['A' num2str(i)]
end
Range =
A1
Range =
A2
Range =
A3
Range =
A4
But,this is a bad way.You should open and write Excel file every time.