MATLAB string to integer conversion - string

I am a newbie at matlab. I have deployed a machine learning model(developed using python) using flask. From matlab, I have called the API and received a string response. The response is like: '[0.8]'. but matlab is showing the size of the string is 1. I need only the value 0.8. My code:
import matlab.net.http.*
import matlab.net.http.field.*
request = RequestMessage( 'POST', ...
[ContentTypeField( 'application/vnd.api+json' ), AcceptField('application/vnd.api+json')], ...
'{"meta": {"Speed_RPM_PU": 0.2}}' );
response = request.send( 'http://127.0.0.1:5000/predict' );
ans=response.Body.Data
length(ans) % equals to 1
% for i = 1:length(ans)
%
% fprintf('%c ',ans(i))
%
% %disp(String(i))
%
% end
Here, ans='[0.8]'

If ans='[0.8]' then length(ans) would be equal to 5 (because there are 5 characters in this char array). I suspect that you actually have ans={'[0.8]'}, i.e. a cell array of length 1 which contains a single char array. Otherwise you are using single quotation marks '_' which indicate a char where MATLAB is actually showing double quotation marks "_" which indicate a string, since the length would be 1 if it was a string too. Chars and strings are not equivalent.
Calling class(ans) instead of length(ans) would tell you which of these is correct.
You can use str2num(ans) in any case, but if it's a cell you'll need str2num(ans{1})
str2num('[0.8]') % = 0.8 (double from char)
str2num("[0.8]") % = 0.8 (double from string)
str2num({'0.8'}) % -> error
a = {'0.8'};
str2num(a{1}) % = 0.8 (double from char element of cell)
str2double is often preferred over str2num, but you would need to remove the square brackets from your char/string or it would give NaN, so something like
str2double( erase( '[0.8]', {'[',']'} ) ) % = 0.8 (double)
Note that ans is the default variable name for unassigned function outputs, consider using a different variable name to avoid unexpected issues.

Related

How to define a function with a parameter one string and return a new string which has the middle char repeated as much as the length of the str

Define a function called repeat_middle which receives as parameter one string (with at least one character), and it should return a new string which will have the middle character/s in the string repeated as many times as the length of the input (original) string.
Notice that if the original string has an odd number of characters there is only one middle character. If, on the other hand, if the original string has an even number of characters then there will be two middle characters, and both have to be repeated (see the example).
Additionally, if there is only one middle character, then the string should be surrounded by 1 exclamation sign in each extreme . If , on the other hand, the original string has two middle characters then the returned string should have two exclamation signs at each extreme.
As an example, the following code fragment:
print (repeat_middle("abMNcd"))
should produce the output:
!!MNMNMNMNMNMN!!
Try the following:
def repeat_middle(string):
l = len(string)
if l % 2 == 0:
return "!!{}!!".format(string[int(l / 2 - .5) : int(l / 2 + 1.5)] * l)
else:
return "{}".format(string[int(l / 2)] * l)
odd = "ham"
even = "spam"
print("Original odd length string: {}".format(odd))
print("Returned string: {}".format(repeat_middle(odd)))
print("")
print("Original even length string: {}".format(even))
print("Returned string: {}".format(repeat_middle(even)))
Where the sample output is:
Original even length string: spam
Returned string: !!papapapa!!
Original odd length string: ham
Returned string: aaa
You will find that print(repeat_middle("abMNcd")) does indeed output !!MNMNMNMNMNMN!!.

Padding with zeros in the middle of a string?

Padding a number with leading zeros has been answered here. But in my case I have a string character followed by digits. I want to add leading zeros after the string character, but before the digits, keeping the total length to 4. For example:
A1 -> A001
A12 -> A012
A123 -> A123
I have the following code that gets me what I want, but is there a shorter way to do this without using re to split my string into text and numbers first?
import re
mystr = 'A4'
elements = re.match(r"([a-z]+)([0-9]+)", mystr, re.I)
first, second = elements.groups()
print(first + '{:0>3}'.format(second))
output = A004
You could use the following to avoid using re:
def pad_center(s):
zeros = '0' * (4 - len(s))
first, *the_rest = list(s)
return first + zeros + ''.join(the_rest)
print(pad_center('A1'))
print(pad_center('A12'))
print(pad_center('A123'))
Or, if you want to use format() you could try this:
def pad_center(s):
zeros = '0' * (4 - len(s))
first, *the_rest = list(s)
return '{}{}{}'.format(first, zeros, ''.join(the_rest))
However, I am not aware of any way to add padding to the center of a string with the format string syntax without prior processing.

Converting int to string then back to int

How do I call out a particular digit from a number. For example: bringing out 6 from 768, then using 6 to multiply 3. I've tried using the code below, but it does not work.
digits = []
digits = str(input("no:"))
print (int(digits[1] * 5))
If my input is 234 since the value in[1] is 3, how can I multiply the 3 by 5?
input() returns a string (wether or not you explicitly convert it to str() again), so digits[1] is still a single character string.
You need to convert that single digit to an integer with int(), not the result of the multiplication:
print (int(digits[1]) * 5)
All I did was move a ) parenthesis there.
Your mistake was to multiply the single-character string; multiplying a string by n produces that string repeated n times.
digits[1] = '3' so digits[1] * 5 = '33333'. You want int(digits[1]) * 5.

String formatting according to number of decimal points

I want to write a string of variable values in a formatted way, according to the following:
Maximum decimal points is 3.
If there are less than 3 significant points than less are written.
For example:
the number 1.53848 will be written as 1.538
the number 1.0 will be written as 1 (rather than 1.000).
val variable1 = 1.
val variable2 = 1.53848
language = "%s average value is %.3f and %.3f".format(variable1, variable2)
This should do the trick:
def format(d: Double) =
BigDecimal(d).scale match {
case x if x > 2 => "%.3f".format(d)
case _ => d.toInt.toString
}
How about just removing the zeroes (and possibly the comma/separator character)?
def formatted(d: Double) = "%.3f".format(d).replaceAll(",?0+$", "")

How do I read a delimited file with strings/numbers with Octave?

I am trying to read a text file containing digits and strings using Octave. The file format is something like this:
A B C
a 10 100
b 20 200
c 30 300
d 40 400
e 50 500
but the delimiter can be space, tab, comma or semicolon. The textread function works fine if the delimiter is space/tab:
[A,B,C] = textread ('test.dat','%s %d %d','headerlines',1)
However it does not work if delimiter is comma/semicolon. I tried to use dklmread:
dlmread ('test.dat',';',1,0)
but it does not work because the first column is a string.
Basically, with textread I can't specify the delimiter and with dlmread I can't specify the format of the first column. Not with the versions of these functions in Octave, at least. Has anybody ever had this problem before?
textread allows you to specify the delimiter-- it honors the property arguments of strread. The following code worked for me:
[A,B,C] = textread( 'test.dat', '%s %d %d' ,'delimiter' , ',' ,1 )
I couldn't find an easy way to do this in Octave currently. You could use fopen() to loop through the file and manually extract the data. I wrote a function that would do this on arbitrary data:
function varargout = coltextread(fname, delim)
% Initialize the variable output argument
varargout = cell(nargout, 1);
% Initialize elements of the cell array to nested cell arrays
% This syntax is due to {:} producing a comma-separated
[varargout{:}] = deal(cell());
fid = fopen(fname, 'r');
while true
% Get the current line
ln = fgetl(fid);
% Stop if EOF
if ln == -1
break;
endif
% Split the line string into components and parse numbers
elems = strsplit(ln, delim);
nums = str2double(elems);
nans = isnan(nums);
% Special case of all strings (header line)
if all(nans)
continue;
endif
% Find the indices of the NaNs
% (i.e. the indices of the strings in the original data)
idxnans = find(nans);
% Assign each corresponding element in the current line
% into the corresponding cell array of varargout
for i = 1:nargout
% Detect if the current index is a string or a num
if any(ismember(idxnans, i))
varargout{i}{end+1} = elems{i};
else
varargout{i}{end+1} = nums(i);
endif
endfor
endwhile
endfunction
It accepts two arguments: the file name, and the delimiter. The function is governed by the number of return variables that are specified, so, for example, [A B C] = coltextread('data.txt', ';'); will try to parse three different data elements from each row in the file, while A = coltextread('data.txt', ';'); will only parse the first elements. If no return variable is given, then the function won't return anything.
The function ignores rows that have all-strings (e.g. the 'A B C' header). Just remove the if all(nans)... section if you want everything.
By default, the 'columns' are returned as cell arrays, although the numbers within those arrays are actually converted numbers, not strings. If you know that a cell array contains only numbers, then you can easily convert it to a column vector with: cell2mat(A)'.

Resources