Function to encoding input characters in MATLAB - arrays

I want to create a function that encrypts the input sentence. This encryption will replace the first letter of each word with the next letter in the ASCII table, and the second letter with the next, ....
So basically, the resulting output for abc def should be bcd efg. However, when I run my function, the space will also be replaced, i.e. output will be bcd!efg. Why is this so? Thanks.
Below is what I have written:
function out = encrypt(input)
ascii_encode=double(input);
line={ascii_encode};
counter=0;
for a=1:length(line)
if line{a}==32
counter=0;
else
counter=counter+1;
line{a}=line{a}+counter;
end
line{a}=char(line{a});
end
out=line;
end

You should be careful handling cells.
Try line{a} , line(a) , line(1){a}, to understand how they work.
The code should be like this,
function out = encrypt(input)
ascii_encode = double(input);
line = {ascii_encode};
for a = 1 : length(line{1})
if line{1}(a) == 32
continue;
end
line{1}(a) = line{1}(a) + 1;
end
line{1} = char(line{1});
out = line{1};
end
And there is no need for counter, you just have to jump when if is true.

Kamtal's answer is perfectly right. You assign your input to a cell and then you were not accessing an index in the cell value (which is still a char array), but the full cell value.
Follow Kamtal answer if you still want to use cells type, and look at the cell documentation.
Note that you could also benefit by Matlab vectorization capabilities, and simplify your function by:
function out = encrypt(input)
charToKeep = ( input==' ' ) ; %// save position of character to keep
out = char(input+1) ; %// apply the modification on the full string
out(charToKeep) = ' ' ; %// replace the character we saved in their initial position
end

Related

how to replace null with 0 in scala array

I am a scala beginner and I face a problem when I am doing my homework because there is null in the text file for example (AFG,Asia,Afghanistan,2020-02-24,1.0,1.0,,,,,0.026,0.026). So, I need to replace the null in array with zero. I read the scala array members and try the update and filter method but I cannot solve it. Can someone help me?
val filename = "relevant.txt" //Access File
val rf = Source.fromFile(filename).getLines.toArray //Read File as Array
for(line <- rf){ //for loop
line.(**How to replace the null with 0?**)
//println(line.split(",")(0))
if (line.split(",")(0).trim().equalsIgnoreCase(iso_code)){ //check for correct ISO CODE , ignores the casing of the input
total_deaths += line.split(",")(4).trim().toDouble //increases based on the respective array position
sum_of_new_deaths += line.split(",")(5).trim().toDouble
record_count += 1 //increment for each entry
}
}
val cells = line.split(",")
.map(_.trim)
.map(it => if (it.isEmpty) "0" else it)
Then you can use it like total_deaths += cells(4).toDouble
BTW, null usually refers to "null pointer" in scala.
In your case, you don't have any "null pointer", you just have "empty string"
What you may do is something like this:
for (line <- rf) {
val data = line.split(',').toList.map(str => Option(str).filter(_.nonEmpty))
}
That way data would be a List[Option[String]] where empty values will be None, then you may use pattern matching to extra the data you want.
if you had to apply the change where you want:
//line.(**How to replace the null with 0?**)
you could do:
val line2 = if (line.trim().isEmpty) "," else line
then use line2 everywhere else.
As a side thing, if you want to do something more scala, replace .toArray with .toList and have a look at how map, filter, sum etc work.

VBA nested for loop won't Run

Hi I'm working on a macro in VBA for excel. I have a nested for loop in my code as seen below. The second loop does not run; even a MsgBox() command within the second loop doesn't result in any action and the program just seems to skip over the nested loop with no reported errors.
In plain English this nested loop should:
1) Take the string from the i entry in the array categories_string (first for loop).
2) iterate through the 300+ rows in column "AE" in the excel file (second for loop, "length" is the length of the column of data in "AE")
3) look for string matches and add 1 to the corresponding entry in the categories_value array which is populated with variables set to 0 (the if statement).
For i = LBound(categories_string) To UBound(categories_string)
For p = 1 To p = length
If Worksheets("sheet1").Cells(p + 2, "AE").Value = categories_string(i) Then
categories_value(i) = categories_value(i) + 1
End If
Next
Next
Change
For p = 1 To p = length
to
For p = 1 To length
Should fix you right up.
You may want to consider Scott Cranner's comment as well, especially if your categories_string is large and length is large. Or, just do it for the practice

Matlab join array of strings

In ruby and other languages, I can create an array, push an arbitrary number of strings and then join the array:
ary=[]
...
ary.push some_str
ary.push some_other_str
...
result = ary.join ""
How do I accomplish this in matlab?
User story: my plot legend is composed of a variable number of strings. The number of strings is determined runtime, so I want to declare the array, add strings dynamically and then join the array to the legend string in the end of the script.
In MATLAB, String joining happens like the following
a = 'ding';
b = 'dong';
c = [a ' ' b]; % Produces 'ding dong'
P.S. a typeof(c,'char') shows TRUE in MATLAB because it "joins" all characters into C.
Suppose you want to start with an empty char placeholder. You can do this.
a = ``; % Produces an empty character with 0x0 size.
Then you can keep adding to the end of it; like this:
a = [a 'newly added'] % produces a = "newly added"
To prove that it works, do this again:
a = [a ' appended more to the end.'] % produces a = "newly added appended more to the end."
You can always use the end keyword that points to the last index of an array, but in this case you need to append to end+X where X is the extra number of characters you are appending (annoyingly). I suggest you just use the [] operator to join/append.
There is also this strjoin(C, delim) function which joins a cell C of strings using a delim delimiter (could be whitespace or whatever). But cheap and dirty one is the one I showed above.

How do I reassign even and odd indices of a character array into a new smaller character array in Matlab?

In matlab I have a 32x1 character array A such that
A = {'F1' 'F2' 'F3' 'F4' 'F5' 'F6' ... 'F32'};
A = A';
Now I am trying to do the following with A.
For every even index of A meaning
A{2}, A{4}, A{6}...
I want to assign those values to a 16x1 character array B and for the odd indices of A I want to assign those values to a different 16x1 array C.
I use the following code:
for i=1:32
if mod(i,2)==0
B{i} = A{i};
else
C{i} = A{i};
end
end
and it works, but only partially because it assigns the right values at for e.g. B{2} and B{4} but the values in B{1} and B{3} are the same as in B{2} and B{4}.
Can anybody tell me how to reassign even and odd indices of a character array into a new smaller character array? My problem is that I am going from a 32x1 into a 16x1 and I'm not sure how to avoid the extra 16 entries.
Many thanks!
To get this question actual answered, use the idea of Luis Mendo in the comments. You can combine it with deal to save one line of code:
[B, C] = deal(A(2:2:end), A(1:2:end))
To make your loop work, you need a second running index jj:
A = {'F1' 'F2' 'F3' 'F4' 'F5' 'F6'};
for ii = 1:6
jj = ceil(ii/2);
if mod(ii,2)==0
B{jj} = A{ii};
else
C{jj} = A{ii};
end
end

Read in file to single array and then check if a number is in that array

I've got a .txt file set up in the following format:
7
8
9
10
What I'm trying to do, is read in the numbers from the file into an array and then check if a number I'm getting from a different function is contained within that array.
ismember(ruleFunc{x+1},memFunc}
I'm pretty sure that will check if the element from ruleFunc is in the array memFunc and return 1/0 if it is or isn't. But I can't get the ismember function to work properly because the method I'm using to populate the memFunc array is wrong.
Additionally, how am I able to add another number to the .txt file on a new line?
EDIT:
Here is how I am populating memFunc currently. It's also the same method that populates ruleFunc.
mem=fopen('WorkingMemory.txt');
tline = fgets(mem);
workMem = {};
index = 1;
while ischar(tline)
workMem{index} = str2num(tline);
tline = fgets(mem);
index = index + 1;
end
The function ismember returns a matrix that is 1 where the inputs are equal. (See the documenation for more information.) You might actually want something that returns a number, 1 or 0, depending on weather or not your number is in the matrix at all. I've included both options below.
% read in file
filename = 'my_data.txt';
fid = fopen(filename);
data = textscan(fid, '%d');
data = data{1};
fclose(fid);
% determine if number is in the file
number = 33;
ismember(data,number) %this returns an array
length(find(data == number)) > 0 % this returns 1 or 0
%write a line to existing file
fid2 = fopen(filename,'a');
newnumber = 100;
fprintf(fid2, '%d\n', newnumber);
fclose(fid2);
Now I see your updated answer. That code will read each line into a different cell of a cell array. You want all your data in a matrix. You could rearrange your cell array and put the data into a matrix or you could use textscan as described above.
In response to your comment, you can make an if statement like this:
if (length(find(data == number)) > 0)
'do something'
end
Maybe you are actually creating an array containing strings instead of numbers?
If it's not as simple as that, more information / code snippets would be useful. You mention the method populating memFunc may be wrong, maybe you could post that code?

Resources