Strrep not working in Matlab to make String into function - string

Hello I am new to MATLAB , I wanted to know how can I make my string into function . I want to access the function as a string from user in standard Matlab format (e.g exp(-10*X)-sin(pi*X)-2*tanh(X) ) Here X is the variable. Then I want to replace 'X' with 'low' and 'high' variables to calculate value of function at these limits. I have used 'strrep' for this purpose. I am getting the following errors
1)Undefined function or variable 'X'.
2) I cannot see whether 'X' was replaced with 'low' and 'high'.
Any help will be truly appreciated.
Below is my code.
high=input('Upper Limit of the Interval : ');
low=input('\nLower Limit of the interval : ');
usr_funct=input('Enter The Function in standard Matlab Format.\nEnter "X" for the
variable and * for multiply \n'); % Example exp(-10*X)-sin(pi*X)-2*tanh(X);
middle = (low+high)/2;
Flow =strrep(usr_funct, 'X', 'low');
Fhigh =strrep(usr_funct, 'X', 'high');
sprintf('Flow '); % This was to check if 'X' was replaced with 'low'. It is not printing anything

Use:
usr_funct=input('Enter The Function...', 's');
This will return the entered text as a MATLAB string, without evaluating expressions.

I think that you are looking for the eval function. That will evaluate a string as matlab code.
Here is an example:
str = 'exp(-10*X)-sin(pi*X)-2*tanh(X)' ; % let str be your math expression
high = 10; % Ask the user
low = -5; % Ask the user
% Now we evaluate for High and Low
X = low; % We want to evaluate for low
ResultLow = eval(str); % That will return your value for X = low
X = high; % We want to evaluate for low
ResultHigh = eval(str); % That will return your value for X = high

1) Undefined function or variable 'X'
If you look at the documentation for input, it says that by default, it evaluates the expression. You need to add a second argument of 's' for it to just save a string.
2) I cannot see whether 'X' was replace with 'low' and 'high'
You should type sprintf(Flow) instead of sprintf('Flow'). The latter will just output "Flow" onto the screen while the former will output the value of Flow.
Finally, the eval function may be of use later on when you actually want to evaluate your expression.

Related

How can I make my function work for any number?

I am having some issues with some code I wrote for this problem:
“Write a function namedd calc that will evaluate a simple arithmetic expression. The input to your program will be a string of the form:
operand1 operator operand2
where operand1 and operand2 are non-negative integers and operator is a single-character operator, which is either +, -, or *. You may assume that there is a space between each operand and the operator. You may further assume that the input is a valid mathemat- ical expression, i.e. your program is not responsible for the case where the user enters gibberish.
Your function will return an integer, such that the returned value is equal to the value produced by applying the given operation to the given operands.
Sample execution:
calc("5 + 10") # 15
“You may not use the split or eval functions in your solution.
Hint: the hard part here is breaking the input string into its three component. You may use the find and rfind functions to find the position of the first and last space, and then use the slice operator (that is, s[startindex:endindex]) to extract the relevant range of characters. Be careful of off-by-one errors in using the slice operator.
Hint: it’s best to test your code as you work. The first step should be to break the input string into its three components. Write a program that does that, have it print out the operator and the two operands on separate lines, and test it until you are convinced that it works. Then, modifying it to perform the desired mathematical operation should be straightforward. Test your program with several different inputs to make sure it works as you expect.”
Here is my code:
def calc(exp):
operand1 = int(exp[:1])
operand2 = int(exp[4:6])
operator = exp[2:3]
if(operator == "+"):
addition = operand1+operand2
return addition
if(operator == "-"):
subtraction = operand1-operand2
return subtraction
if(operator == "*"):
multiplication = operand1*operand2
return multiplication
print(calc("5 + 10"))
print(calc("4 - 8"))
print(calc("4 * 3"))
My code does not fully meet the criteria of this question. It only works for single digit numbers. How can I make my code work for any number?
Like:
“504 + 507”
”5678 + 76890”
and so on?
Thank you. Any help is appreciated.
As the hint says, get the position of the first and last space of the expression, use it to extract the operand and the operators, and then evaluate accordingly.
def calc(exp):
#Get the position for first space with find
low_idx = exp.find(' ')
#Get the position for last space with rfind
high_idx = exp.rfind(' ')
#Extract operators and operand with slice, converting operands to int
operand1 = int(exp[0:low_idx])
operator = exp[low_idx+1:high_idx]
operand2 = int(exp[high_idx:])
result = 0
#Evaluate based on operator
if operator == '+':
result = operand1 + operand2
elif operator == '-':
result = operand1 - operand2
elif operator == '*':
result = operand1 * operand2
return result
print(calc("5 + 10"))
print(calc("4 - 8"))
print(calc("4 * 3"))
print(calc("504 + 507"))
print(calc("5678 + 76890"))
#15
#-4
#12
#1011
#82568
The answer is in the specification:
You may use the find and rfind functions to find the position of the first and last space, and then use the slice operator (that is, s[startindex:endindex]) to extract the relevant range of characters.
find and rfind are methods of string objects.
You could split it into three components using this code: (note: this doesn't use split or eval)
def splitExpression(e):
numbers = ["1","2","3","4","5","6","7","8","9","0"] # list of all numbers
operations = ["+","-","*","/"] # list of all operations
output = [] # output components
currentlyParsing = "number" # the component we're currently parsing
buildstring = "" # temporary variable
for c in e:
if c == " ":
continue # ignore whitespace
if currentlyParsing == "number": # we are currently parsing a number
if c in numbers:
buildstring += c # this is a number, continue
elif c in operations:
output.append(buildstring) # this component has reached it's end
buildstring = c
currentlyParsing = "operation" # we are expecting an operation now
else:
pass # unknown symbol!
elif currentlyParsing == "operation": # we are currently parsing an operation
if c in operations:
buildstring += c # this is an operation, continue
elif c in numbers:
output.append(buildstring) # this component has reached it's end
buildstring = c
currentlyParsing = "number" # we are expecting a number now
else:
pass # unknown symbol!
if buildstring: # anything left in the buffer?
output.append(buildstring)
buildstring = ""
return output
Usage: splitExpression("281*14") returns ["281","*","14"]
This function also accepts spaces between numbers and operations
You can simply take the string and use the split method for the string object, which will return a list of strings based on some separator.
For example:
stringList = "504 + 507".split(" ")
stringList will now be a list such as ["504", "+", "507"] due to the separator " " which is a whitespace. Then just use stringList[1] with your conditionals to solve the problem. Additionally, you can use int(stringList[0]) and int(stringList[2]) to convert the strings to int objects.
EDIT:
Now I realized that your problem said to use find() instead of split(). Simply use the logic above but instead find(" ") the first whitespace. You will then need to find the second whitespace by slicing past the first whitespace using the two additional arguments available for find().
You need to split the string out instead of hard coding the positions of the indexes.
When coding you want to try to make your code as dynamic as possible, that generally means not hard coding stuff that could be a variable or in this case could be grabbed from the spaces.
Also in the if statements I modified them to elif as it is all one contained statement and thus should be grouped.
def calc(exp):
vals = exp.split(' ')
operand1 = int(vals[0])
operand2 = int(vals[2])
operator = vals[1]
if operator == '+':
return operand1+operand2
elif operator == '-':
return operand1-operand2
else:
return operand1*operand2

Beginner python - simple Pounds to Kilos

The instructions are very simple, but I am struggling none the less. We have learned very few things in this class so far, so I am looking for a very simplistic answer.
The instructions are as follows "Write a Python program that will prompt the user to enter a weight in pounds, then
convert it to kilograms and output the result. Note, one pound is .454 kilograms"
What i have so far is
print("Pounds to Kilos. Please Enter value in pounds.")
x=input('Pounds: ')
float(x)
print(x * .454)
You are converting the variable x's value to the float, but not assigning it to anything. So, the real value which x variable holds never changed. You did not edit the x variable in fact. You can try something like this;
print("Pounds to Kilos. Please Enter value in pounds.")
x=float(input('Pounds: '))
print(x * .454)
However, using functions in that nested manner is not recommended. Instead, initialize a new variable to hold the new float-converted value;
print("Pounds to Kilos. Please Enter value in pounds.")
x = input('Pounds: ')
x_float = float(x)
print(x_float * .454)
Going from your code example I would do something like this.
print("Pounds to Kilos. Please Enter value in pounds.")
x = float(input('Pounds: '))
print(x * 0.454, "kg")
EDIT
Maybe instead of having the calculation in the print() statement I add a separate variable for it, including the advise about float from the other solution.
print("Pounds to Kilos. Please Enter value in pounds.")
x = (input('Pounds: '))
kg = float(x) * 0.454
print(kg, "kg")
Explanation: First you ask the user's weight using input command, then you can print a message saying converting to kgs.. (it's optional). create a new variable called weight_kgs to convert the user's input to a float, then multiply the input by 0.45. after that convert the weight_kgs variable to a string once again by making a new variable called final_weight, so that you can join the input by user to a string. At the end print a message telling the user's weight. print("you weight is " + final_weight)
```
weight_lbs = input("enter your weight(lbs): ")
print("converting to kgs...")
weight_kgs = float(weight_lbs) * 0.45
final_weight = str(weight_kgs)
print("your weight is " + final_weight + "kgs") # line 5
```
I hope you got it.

Comparing spaces in python

I am creating a cipher script in python without any modules but I have come accross a problem that i cant solve. When I am comparing msg[3] which has the value (space) it should be equal to bet[26] which is also a space. If i compare msg[3] with bet[26] in the shell...
>>>msg[3] == bet[26]
True
The output is True. However when i run the program and output the value of enmsg there is no value 26 where the value 26 should be.
enmsg = []
msg = "try harder"
bet = "abcdefghijklmnopqrstuvwxyz "
for x in range(0, len(msg)):
for i in range(0, 26):
if msg[x] == bet[i]:
print(msg[x])
enmsg.append(i)
You should get out of the habit of iterating over a range of indices and then looking up the value at the index. Instead iterate directly over your iterables, using enumerate when necessary.
enmsg = []
msg = "try harder"
bet = "abcdefghijklmnopqrstuvwxyz "
for msg_char in msg:
for index, bet_char in enumerate(bet):
if msg_char == bet_char:
print(msg_char)
enmsg.append(index)
Your second loop iterations are too short so it is not reaching the space symbol.
Try with this:
enmsg = []
msg = "try harder"
bet = "abcdefghijklmnopqrstuvwxyz "
for x in range(0, len(msg)):
for i in range(len(bet)):
if msg[x] == bet[i]:
print(msg[x])
enmsg.append(i)
The upper bound of range is not inclusive; you'll need to extend this by one to actually check the 26th index of the string. Better yet, iterate up through len(bet) as you did for len(msg) for the outer loop.

how to convert decimal to binary by using repeated division in python

how to convert decimal to binary by using repeated division in python?
i know i have to use a while loop, and use modulus sign and others {%} and {//} to do this...but i need some kind of example for me to understand how its done so i can understand completely.
CORRECT ME, if I'm wrong:
number = int(input("Enter a numberto convert into binary: "))
result = ""
while number != 0:
remainder = number % 2 # gives the exact remainder
times = number // 2
result = str(remainder) + result
print("The binary representation is", result)
break
Thank You
Making a "break" without any condition, makes the loop useless, so the code only executes once no matter what.
-
If you don't need to keep the original number, you can change "number" as you go.
If you do need to keep the original number, you can make a different variable like "times".
You seem to have mixed these two scenarios together.
-
If you want to print all the steps, the print will be inside the loop so it prints multiple times.
If you only want to print the final result, then the print goes outside the loop.
while number != 0:
remainder = number % 2 # gives the exact remainder
number = number // 2
result = str(remainder) + result
print("The binary representation is", result)
-
The concatenation line:
Putting the print inside the loop might help you see how it works.
we can make an example:
the value in result might be "11010" (a string, with quotes)
the value in remainder might be 0 (an integer, no quotes)
str(remainder) turns the remainder into a string = "0" instead of 0
So when we look at the assignment statement:
result = str(remainder) + result
The right side of the assignment operator = is evaulated first.
The right side of the = is
str(remainder) + result
which, as we went over above has the values:
"0" + "11010"
This is string concatenation. It just puts one string on the end of the other one. The result is:
"0 11010"
"011010"
That is the value evaluated on the right side of the assignment statement.
result = "011010"
Now that is the value of result.
B_Number = 0
cnt = 0
while (N != 0):
rem = N % 2
c = pow(10, cnt)
B_Number += rem * c
N //= 2
# Count used to store exponent value
cnt += 1
return B_Number

Determining Moves and Outcomes for Tic-Tac-Toe in MATLAB W/ Helper Function

Note: I am up-dating this as I go along. I add in comments to let you know if I added in code or not. Since I have no comments, I doubt anyone will get confused. And to whomever down-voted me, I'm putting in as much information as I can. Calm yourself.
That's a pretty long title, but it sums up everything I need to do for this problem. I am given a tic-tac-toe board in the form of a 3x3 cell and a string that tells me whose move it is (Player X or Player O). I need to out a 2xN cell that lists what possible moves can be made, and what the outcome of that move would be. For example, the the player is Player X and my board looks like:
{ 'x' 'o' 'x'
'o' 'x' 'o'
'o' ' ' ' ' }
Then my options are
{ 'x' 'o' 'x' {'x' 'o' 'x'
'o' 'x' 'o' 'o' 'x' 'o'
'o' 'x' ' '} 'o' ' ' 'x'}
'Your move, player O.' 'Player X Wins!' }
Blanks spots are always indicated by a space. Now for this problem, I've been given a helper function called 'moveEvaluater' that looks like this:
Helper Function Name: moveEvaluator
Helper Function Inputs (2): - (char) A 3x3 character array representing
a tic tac toe board, after a move
has been made.
- (char) A single character of the the
player that just moved.
Helper Function Outputs (1): - (char) A string indicating the outcome
of the turn.
The helper function moveEvaluator takes in a 3x3 character array of a
tic tac toe board after a move has been made, with spaces used to
represent the empty spaces on the board, and a single character of the
player who just went. This 2nd input will be a string of either 'x' or
'o'. This helper function will then output the outcome of that turn: if
it was player X's turn, then the two possible outcomes are 'Player X
Wins!' or 'Your turn, player O.' Similarly, if it was player O's turn,
then the two possible outcomes are 'Player O Wins!' or 'Your turn,
player X.'
So this basically does half my function for me. I seem to have this working thanks to Hoki :)
function[Move_Choices] = ticTacToeTurn(Board, str)
charBoard = reshape(char(Board) , 3 , 3 ) ;
PlayerSymbol = str ;
% Find the indices of possible move
Move_Choices = find(ismember(Board, ' '));
% // count them
nChoices = numel(Move_Choices) ;
% // pre-allocate output
outcome = cell(nChoices,1) ;
Options = '';
Strings = '';
% // Get outcome for each possible postition
for iSlot = 1:nChoices
PossibleBoard = charBoard ; % // copy the initial board
PossibleBoard(Move_Choices(iSlot) ) = PlayerSymbol;% // Add an 'x' at one of the empty position
disp(PossibleBoard) ; % display the currently played board / optional, just for your information
PossibleBoard = char(PossibleBoard);
outcome = moveEvaluator(PossibleBoard, str);
Strings = [Strings {outcome}];
end
for iSlot = 1:nChoices
PossibleBoard = charBoard ; % // copy the initial board
PossibleBoard(Move_Choices(iSlot) ) = PlayerSymbol;% // Add an 'x' at one of the empty position
disp(PossibleBoard) ; % display the currently played board / optional, just for your information
PossibleBoard = cellstr(PossibleBoard);
Options = [Options, {PossibleBoard}];
end
Move_Choices = [Options;Strings]; %// Here's my issue. This outputs a cell, but the cellstr function separated the x's and o's into cells of three. I need each spot to be their own cell :/
end
I just need it to fill in the one x in either slot, not both. Furthermore, I need to do is figure out how to use the helper function from here to output what the possible string options there are.
Testcases:
board1 = { 'x' 'o' 'x'
'o' 'x' 'o'
'o' ' ' ' ' }
move1 = 'x'
possibleMoves1 = ticTacToeTurn(board1,move1)
This should give be a 2x2 cell that looks like:
Cell (1,1) This is a cell inside a cell. All of the 'x' and 'o's are a separate cell
{'x''o' 'x'
'o' 'x' 'o'
'o' 'x' ' '}
Cell (2,1) looks is the string that says "Your move, Player O"
Cell (1,2) Should be
{ 'x' 'o' 'x'
'o' 'x' 'o'
'o' ' ' 'x'}
Cell (2, 2) looks is the string that says "Player X wins!'
I tried to look at the code for the evaluator function, but it's apparently a p file so I'm not too sure what to do. Any help would be appreciated :) Let me know if I missed anything. Should be all.
Ok, seeing you tried a bit by yourself I'll point you in the final direction. This is not a "function" and so it is not a direct answer to your assignment but it includes the complete resolution of the problem. You just have to repackage it into your function.
%% // Initial conditions
Board = {'x' 'o' 'x'
'o' 'x' 'o'
'o' ' ' ' ' };
charBoard = reshape( char(Board) , 3 , 3 ) ;
PlayerSymbol = 'x' ;
%% // Resolution
% // Find the indices of possible move
Move_Choices = find(ismember(Board, ' '));
% // count them
nChoices = numel(Move_Choices) ;
% // pre-allocate output
outcome = cell(nChoices,1) ;
% // Get outcome for each possible postition
for iSlot = 1:nChoices
PossibleBoard = charBoard ; % // copy the initial board
PossibleBoard( Move_Choices(iSlot) ) = PlayerSymbol ; % // Add an 'x' at one of the empty position
disp(PossibleBoard) ; % display the currently played board / optional, just for your information
outcome(iSlot) = moveEvaluator( PossibleBoard , PlayerSymbol ) ;
end
A bit of advice: Matlab is an interpreted language. This type of programming language has its pro and cons, but it is great for one thing, you can execute lines of code and directly see the result without the need for a complex debugger.
So you can try many different expressions and refine it until the output is what you are looking for. Seeing the way your initial code was organised, it looks like you could benefit a lot from that. Try to solve your problem bit by bit in the base workspace first until you get a good grasp on your problem and its solution. At this stage it will be a lot easier to put it into a function (just have to work out the input/output, but the core of the calculations is already solved).

Resources