MATLAB: Outputting cell vectors that contain specific information help

cellsfor loops

I am trying to formulate a code that takes in input cell array of strings, evaluates the contents of each cell and outputs the cells that contain only uppercase letters
i.e.
cell =
3×2 cell array
{'ABC'} {'Abc'}
{'DEF'} {'dEf'}
{'GHI'} {'ghi'}
ans =
ABC
DEF
GHI
Here's my code so far:
function uppercase = all_caps(cell)
[rows, cols] = size(cell);
for ii = 1:rows
for jj = 1:cols
if contains(cell{ii, jj}, (['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
uppercase = [uppercase, cell{ii,jj}];
end
end
end
end
fprintf('%s\n', uppercase)
end
How can I use MATLABS assortment of built-in functions to prevent me from typing out each individual letter? Additionally, this method doesn't even work.
My professor showed us this solution:
function all_caps(c_in)
[rows, cols] = size(c_in);
for ii = 1:rows
for jj = 1:cols
str = c_in{ii, jj};
if sum(str >= 'A' & str <= 'Z') == length(str)
fprintf('%s\n', str);
end
end
end
end
I am confused about his if statement. I have no clue what the inside is going on inside the sum() function. Please help.
I know these are "two separate questions," but they are about the same function and regard the same topic.

Best Answer

You can use the colon operator to generate a character vector containing each lower case letter in the alphabet:
>> 'a':'z'
ans =
'abcdefghijklmnopqrstuvwxyz'
Same with upper case letters:
>> 'A':'Z'
ans =
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
Or this, if you want:
>> 'A':'z'
ans =
'ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz'
See here for more info. You can use double() and char() to switch between number and corresponding character:
>> double('a')
ans =
97
>> char(97)
ans =
'a'
So, 'a':'z' is kind of like
>> char(double('a'):double('z'))
ans =
'abcdefghijklmnopqrstuvwxyz'
When you compare characters,
>> 'a' < 'z'
ans =
logical
1
this is like
>> double('a') < double('z')
ans =
logical
1
or rather
>> 97 < 122
ans =
logical
1
In your professor's code:
str >= 'A' & str <= 'Z'
Here, each character within str is being compared to 'A' and 'Z'. The output is a logical array with the same size as str, containing a 1 where the corresponding character of str is between 'A' and 'Z' (i.e. somewhere within the array 'A':'Z').
>> 'GHSIEVBSK' >= 'A' & 'GHSIEVBSK' <= 'Z'
ans =
1×9 logical array
1 1 1 1 1 1 1 1 1
Here, str has all capital letters, so every element in the output is true.
>> 'GhSIeVBsK' >= 'A' & 'GhSIeVBsK' <= 'Z'
ans =
1×9 logical array
1 0 1 1 0 1 1 0 1
Here, some characters in str are lower-case. The corresponding elements in the output are false. With
if sum(str >= 'A' & str <= 'Z') == length(str)
your professor is checking that every element in the output is a 1. Also valid would be
if all(str >= 'A' & str <= 'Z')
Take another look at the documentation for contains.
>> contains('abc', 'a':'z')
ans =
logical
0
This returns 0 because the entirety of 'a':'z' is not found within 'abc'. To check if any element of 'a':'z' is within 'abc', you could use for example
>> contains('abc', cellstr(('a':'z')')')
ans =
logical
1