Matlab coding help - for/while construct

Hello. I am trying to make my morse code encoder program accept strings and allow me to write a whole word. Currently it will only accept single letters/digits and reject anything else. I am extremely confused and can't seem to get it right. Please help. Here is what I could muster up so far:
MC_1='.----'; MC_2='..---'; MC_3='...--';
MC_4='....-'; MC_5='.....'; MC_6='-....';
MC_7='--...'; MC_8='---..'; MC_9='----.';
MC_0='-----'; MC_A='.-'; MC_B='-...';
MC_C='-.-.'; MC_D='-..'; MC_E='.';
MC_F='..-.'; MC_G='--.'; MC_H='....';
MC_I='..'; MC_J='.---'; MC_K='-.-';
MC_L='.-..'; MC_M='--'; MC_N='-.';
MC_O='---'; MC_P='.--.'; MC_Q='--.-';
MC_R='.-.'; MC_S='...'; MC_T='-';
MC_U='..-'; MC_V='...-'; MC_W='.--';
MC_X='-..-'; MC_Y='-.--'; MC_Z='--..';
Word=input('Enter Word to encode here: ','s');
Word=upper(Word);
Valid = 1;
switch(Word)
case '1'
Code=MC_1;
case '2'
Code=MC_2;
case '3'
Code=MC_3;
case '4'
Code=MC_4;
case '5'
Code=MC_5;
case '6'
Code=MC_6;
case '7'
Code=MC_7;
case '8'
Code=MC_8;
case '9'
Code=MC_9;
case '0'
Code=MC_0;
case 'A'
Code=MC_A;
case 'B'
Code=MC_B;
case 'C'
Code=MC_C;
case 'D'
Code=MC_D;
case 'E'
Code=MC_E;
case 'F'
Code=MC_F;
case 'G'
Code=MC_G;
case 'H'
Code=MC_H;
case 'I'
Code=MC_I;
case 'J'
Code=MC_J;
case 'K'
Code=MC_K;
case 'L'
Code=MC_L;
case 'M'
Code=MC_M;
case 'N'
Code=MC_N;
case 'O'
Code=MC_O;
case 'P'
Code=MC_P;
case 'Q'
Code=MC_Q;
case 'R'
Code=MC_R;
case 'S'
Code=MC_S;
case 'T'
Code=MC_T;
case 'U'
Code=MC_U;
case 'V'
Code=MC_V;
case 'W'
Code=MC_W;
case 'X'
Code=MC_X;
case 'Y'
Code=MC_Y;
case 'Z'
Code=MC_Z;
otherwise
Valid =0;
end
if Valid
disp(Code);
else
disp('Error: Invalid Character(s)');
end
I do not want to use MatLab cell arrays (e.g. {'.--.'; '.-.'; '---'; ...}) as I would prefer to just make small revisions and additions to my program.
This is how I want to add to it but not sure how:
for index= ...
% find out the Morse code of the corresponding character in Word.
...
% print out the Morse code
...
end
My goal is for it to look like this in the end:
>> step2
The word to be encoded: Programming
The Morse code is .--. .-. --- --. .-. .- -- -- .. -. --
Thank you so much for any help.

 Accepted Answer

I would do it a bit differently:
Ltrs = {'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' 'O' 'P' 'Q' 'R' 'S' 'T' 'U' 'V' 'W' 'X' 'Y' 'Z' '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' '/'};
IMC = {'.-' '-...' '-.-.' '-..' '.' '..-.' '--.' '....' '..' '.---' '-.-' '.-..' '--' '-.' '---' '.--.' '--.-' '.-.' '...' '-' '..-' '...-' '.--' '-..-' '-.--' '--..' '-----' '.----' '..---' '...--' '....-' '.....' '-....' '--...' '---..' '----.' '-..-.'};
Message = {'P' 'R' 'O' 'G' 'R' 'A' 'M' 'M' 'I' 'N' 'G' '/' 'N' '0' 'K' 'F'};
for k1 = 1:length(Message)
Lgv = cellfun(@(x)ismember(Ltrs, x), Message(k1), 'Uni',0);
Loc = find(Lgv{:});
Morse{k1} = IMC{Loc};
end
Morse
This could likely be made more efficient, but it works.
73 DE N0KF

13 Comments

I totally understand what you're doing here. This seems much easier and efficient then what I am trying to achieve but would you be able to help me improve on what I am trying to do? Walter was trying to help me but I still do not get it. I just want to improve upon what I already have because I want to learn this specific method. It may be more tedious but I'm ready to get typing!
I just happened to check my email tonight or I’d likely not have seen this until morning.
Walter is instructing you to do exactly what I did in my code — loop through whatever your message is one character at a time, and assign a new Morse equivalent to your output message with each iteration of the loop, appending it to what you already have. It would be best to use a cell array for your output, although if you use a character array, you will have to use a ‘|’ character to separate the letters because a character array will concatenate them by default and you won’t be able to distinguish the individual Morse letters.
The method you use is correct, but you have to construct your Morse string a letter at a time and concatenate it as you go. I created a concatenated series of indices instead of letters directly, but you have to concatenate your Morse strings because of the way you constructed your code.
73 DE N0KF
But I want to be able to type in any message and have it spit out the morse code. I want it to ask me what I want to encode and when I provide letters/digits it should spit out a code on one line.
Use the inputdlg function. You will still have to split the result letter-by-letter, but that is relatively straightforward.
This should get you started:
MessageCell = inputdlg('Type the message you want transformed into International Morse Code: ');
Message = MessageCell{:};
Wouldn't that make me have to change the morse code into cell arrays?
Not necessarily, the way you coded it. You can save them as a cell array, so that the output could be (using my earlier code):
Output = Morse
Output =
'.--.' '.-.' '---' '--.' '.-.' '.-' '--' '--' '..' '-.' '--.'
If you coded it to be a string array (I did not), it would be perhaps:
Output =
'|.--.|.-.|---|--.|.-.|.-|--|--|..|-.|--.|'
You would have to include the vertical bar in your code or the Morse letters would run together.
My complete code (updated) would now be:
Ltrs = {'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' 'O' 'P' 'Q' 'R' 'S' 'T' 'U' 'V' 'W' 'X' 'Y' 'Z' '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' '/' ' '};
IMC = {'.-' '-...' '-.-.' '-..' '.' '..-.' '--.' '....' '..' '.---' '-.-' '.-..' '--' '-.' '---' '.--.' '--.-' '.-.' '...' '-' '..-' '...-' '.--' '-..-' '-.--' '--..' '-----' '.----' '..---' '...--' '....-' '.....' '-....' '--...' '---..' '----.' '-..-.' ' '};
MessageCell = inputdlg('Type the message you want transformed into International Morse Code: ');
Message = MessageCell{:};
for k1 = 1:length(Message)
Lgv = cellfun(@(x)ismember(Ltrs, x), {Message(k1)}, 'Uni',0);
Loc = find(Lgv{:});
Morse{k1} = IMC{Loc};
end
Output = Morse
Awesome. However, I am getting this error when trying to execute the program:
No right hand side value for assignment.
Error in StarsMorseCode (line 8) Morse{k1} = IMC{Loc};
Also, I noticed that a special window pops up asking for the message you want transformed. What do I have to change to make it so that it asks me in the command window?
Edit: I changed inputdlg to input and added 's' at the end but now I get a new error:
>>StarsMorseCode
Type the message you want transformed into International Morse Code: hey
Cell contents reference from a non-cell array object.
Error in StarsMorseCode (line 4) Message = MessageCell{:};
You have to type in ALL CAPS in my code. I didn’t put an upper call in it. With that, it worked for me. (I also added a space. There is no space character in International Morse, only the period '.-.-.-', question mark '..--..', and comma '--..--' are generally used on the air, and pauses work for spaces. IMC relies on the ability of operators to parse the message.)
I always use inputdlg because it doesn’t pollute my Command Window. If you want to use the Command Window instead, just use the input function. It just returns a text string, not a cell, so you would have to make appropriate changes to my code.
All you need to do in your code is to figure out a way of concatenating the Morse characters to compose a final message, and add it. You do not have to change the rest of it. To create a text string, you need to add a vertical separator between the letters, but otherwise just concatenate.
I finally got it to work the way you said to. However, if using MatLab cell arrays (e.g. {'.--.'; '.-.'; '---'; ...}) is not allowed; how can I go about it?
So here is what I have so far just to show you:
MC_1='.----'; MC_2='..---'; MC_3='...--';
MC_4='....-'; MC_5='.....'; MC_6='-....';
MC_7='--...'; MC_8='---..'; MC_9='----.';
MC_0='-----'; MC_A='.-'; MC_B='-...';
MC_C='-.-.'; MC_D='-..'; MC_E='.';
MC_F='..-.'; MC_G='--.'; MC_H='....';
MC_I='..'; MC_J='.---'; MC_K='-.-';
MC_L='.-..'; MC_M='--'; MC_N='-.';
MC_O='---'; MC_P='.--.'; MC_Q='--.-';
MC_R='.-.'; MC_S='...'; MC_T='-';
MC_U='..-'; MC_V='...-'; MC_W='.--';
MC_X='-..-'; MC_Y='-.--'; MC_Z='--..';
Word = input ('Enter the word to encode to morse code: \n','s');
Word = upper(Word);
morse={'.----','..---','...--','....-','.....','-....','--...','---..','----.','-----','.-','-...','-.-.','-..','.','..-.','--.','....','..','.---','-.-','.-..','--','-.','---','.--.','--.-','.-.','...','-','..-','...-','.--','-..-','-.--','--..','/'};
letter={'1','2','3','4','5','6','7','8','9','0','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','_'};
for index=1:length(Word)
[~, index] = ismember(Word(index), letter);
if index > 0
fprintf('%s', morse{index});
end
end
disp(Word)
>> morsecodeencoder Enter the word to encode to morse code: 12 .----..---12
The problem is that its putting 12 at the end AND I want to remove the cell arrays and do it. I'm not sure how to concatenate it like you said earlier.
I’d prefer you use your code, since you put so much work into it.
You need to do as Walter said, and concatenate your MC_ variables using your switch structure. So for example, if you are concatenating ‘P’ and ‘R’, the loop that creates your Morse Code string would work like this:
Out = [];
Out = [Out '|' MC_P];
Out = [Out '|' MC_R];
Out = [Out '|']
Out =
|.--.|.-.|
First and foremost sorry for all the stupid questions. Also, please reply at your leisure although I truly appreciate your help. Is this what you mean?
case 'A'
Code=MC_A;
for A = 1 : 5
switch Word(A)
Out = [Out '|' MC_A];
case 'B'
Code=MC_B;
for B = 1 : 5
switch Word(B)
Out = [Out '|' MC_B];
I didn’t run that, but yes that’s the essence of what I described, although I don’t understand the nested loops. You need one loop that iterates through your input string and assigns the appropriate elements to ‘Out’ at each iteration until it’s finished.
There are no ‘stupid questions’!

Sign in to comment.

More Answers (1)

Do not switch on Word, switch on Word indexed at a particular character. This would involve a "for" (or while) loop from 1 to the length of the word.
Do not just assign to Code: initialize Code to empty and then for every character, append the new information to the end of Code.

1 Comment

CompleteCode = '';
for K = 1 : 5
switch Word(K)
...
end
CompleteCode = [CompleteCode, Code];
end

Sign in to comment.

Categories

Community Treasure Hunt

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

Start Hunting!